← Maqolalarga qaytish
August 14, 2026
5 daqiqa o'qish

Model Pruning for Low-Latency Trading Inference

Model Pruning for Low-Latency Trading Inference
#model-compression
#pruning
#lottery-ticket
#latency
#deployment

Bizning DeepLOB maqolamiz joylashtirish bo'limini uchta o'q bilan yakunlaydi - ONNX plus TensorRT, INT8 kvantlash, FPGA - va ularning hech biriga ishlov berilmaydi. Ushbu maqola uchta muammo ostidagi birinchi muammoning yo'qolgan davolashidir: model kerak bo'lganidan kattaroqdir. Neyron tarmoqni kesish ortiqcha parametrlarni olib tashlaydi va adabiyotdagi qiziq da'vo shundaki, bu xotirani tejash emas, balki og'irliklarning 10-20% ni ushlab turadigan pastki tarmoq zich modelning aniqligiga mos kelishi mumkin.

Kechikishning muhimligi blog allaqachon qilgan ishdir - ZigBolt xabar almashish yo'lida va IPC solig'i zararsiz arifmetika bilan — va tarqalgan modellashtirish allaqachon tez-lekin biroz yomonroq va sekin-lekin yaxshiroq almashinuvga ega bo‘lib, xulosa chiqarish-kechikish qatoriga ega bo‘lgan gradientni kuchaytiruvchi-chuqur o‘rganish jadvali bilan to‘la. Ularning hech biri qamrab ololmaydigan narsa - berilgan modelni qanday qilib kichikroq qilish. Iqtiboslar davrasidagi bosqichlardan model xulosasi to'liq bizning nazoratimiz ostidadir; transport oyoqlari algotrading uchun ma'lumotlar aloqasi da qayta tiklanadigan p50/p95/p99 raqamlari bilan qoplangan.

**Ushbu maqola nima?

Bu maqola nima: magnituda bo‘yicha va strukturaviy pruning, Iterative Magnitude Pruning, movement pruning, bilimlarni distillash hamda NVIDIA 2:4 yarim strukturaviy siyraklik uchun matematika va ishlaydigan kod, barchasi savdo MLPsiga qo‘llanadi.

Pruning sizga nima beradi

Tezkor kesh qatlamiga mos keladigan ixcham neyron tarmoq

Cheklov bitta o'lchamdir. O'rta chastotali modelni ko'rib chiqing - 2048 ta yashirin birliklarga ega 4 qatlamli MLP buyurtma kitobi xususiyatlariga ko'ra:

Parameters=dinh+h2(L1)+hdout\text{Parameters} = d_{\text{in}} \cdot h + h^2 \cdot (L - 1) + h \cdot d_{\text{out}}

uchundin=100d_{\text{in}} = 100, h=2048h = 2048, L=4L = 4, dout=3d_{\text{out}} = 3, bu taxminan 12,6 million parametr - float32 da taxminan 48 MB. L2 odatda 1-4 MB ni tashkil qiladi, shuning uchun og'irliklar mos kelmaydi; ular har bir oldinga o'tishda uzoqdan uzatiladi. Ularning 95 foizini kesib tashlang va siz taxminan 630K samarali parametr va 2,4 MB ga egasiz, bu mos keladi.

Bu devor soati vaqtiga aylantiriladimi, yadro xotiraga bog'langanmi yoki yo'qligiga bog'liq va bu o'lcham savolidan ko'ra arifmetik intensivlik savolidir. Dvigatel tezligining orqadagi narvon tom chizig'i modelini (Uilyams, Uoterman va Patterson) jarima omilini tasdiqlashdan ko'ra o'lchovli misol orqali ishlaydi; Bu erda bir xil ramka qo'llaniladi va bir xil intizom: tezlikni talab qilishdan oldin ko'chirilgan baytlarni o'lchash kerak.

Pruning asoslari

Neyron panjara boʻylab tuzilgan va tuzilmagan kesish

Strukturaga kirmaydigan pruning

Eng oddiy yondashuv: individual og'irliklarni ularning kattaligiga qarab nolga qo'ying. Og'irlik matritsasi berilganWRm×n\mathbf{W} \in \mathbb{R}^{m \times n}, ikkilik niqob yaratingM{0,1}m×n\mathbf{M} \in \{0, 1\}^{m \times n}shunday qilib:

Mij={1if Wijτ0if Wij<τM_{ij} = \begin{cases} 1 & \text{if } |W_{ij}| \geq \tau \\ 0 & \text{if } |W_{ij}| < \tau \end{cases}

qayerdaτ\taukerakli siyraklik darajasiga erishish uchun tanlangan chegara hisoblanadiss:

s=1M0mns = 1 - \frac{\|\mathbf{M}\|_0}{m \cdot n}

Kesilgan matritsaW=WM\mathbf{W}' = \mathbf{W} \odot \mathbf{M}, bilan\odotHadamard mahsuloti. Sezgi shundaki, nolga yaqin og'irliklar qatlam chiqishiga ozgina hissa qo'shadi.

Muammo aniq ko'rsatilgan, chunki siyraklik raqamini noto'g'ri o'qish oson: tuzilmagan siyraklik standart uskunada tezlikni oshirmaydi. 90% nolga ega matritsa, agar siz siyrak yadrolarga yoki siyraklikni qo'llab-quvvatlaydigan uskunaga o'tmasangiz, bir xil miqdordagi ko'payish to'planishini chiqaradi. Quyidagi kod chop etilgandaSparsity: 90.0%, bu nollarning soni - bu 10x hech narsa emas va zich GEMM protsessorida bu ham 1.01x emas. Vaqtni sotib oladigan yo'llar quyida tuzilgan budama (kichikroq matritsalar) va 2:4 yarim tuzilgan siyraklik (apparat yordami) hisoblanadi.

Strukturaviy pruning

Strukturaviy kesish butun neyronlarni, kanallarni yoki diqqat boshlarini olib tashlaydi. Chiziqli qatlam uchuny=Wx+b\mathbf{y} = \mathbf{W}\mathbf{x} + \mathbf{b}bilanWRm×n\mathbf{W} \in \mathbb{R}^{m \times n}, neyronni olib tashlashjjnolga tengjj- qatorW\mathbf{W}vajj- ning elementib\mathbf{b}:

importance(j)=Wj,:2=k=1nWjk2\text{importance}(j) = \|\mathbf{W}_{j,:}\|_2 = \sqrt{\sum_{k=1}^{n} W_{jk}^2}

Eng kichik neyronlar2\ell_2-norma birinchi bo'lib. Bu haqiqatan ham kichikroq matritsalarni ishlab chiqaradigan variant - lekin faqat qatlamlarni qayta tiklasangiz. Qatorlarni nol qilish va tensorni asl shaklida qoldirish FLOP soni haqida hech narsani o'zgartirmaydi; amalga oshirish bo'limida qayta qurish bosqichi a ga niqob o'zgartiradi nima512×n512 \times nmatritsa.

Konvolyutsion qatlamlar uchun analog filtrni kesishdir. BerilganWRCout×Cin×k×k\mathbf{W} \in \mathbb{R}^{C_{\text{out}} \times C_{\text{in}} \times k \times k}, chiqish filtrining ahamiyatiiibu:

importance(i)=Wi,:,:,:F=c,h,wWi,c,h,w2\text{importance}(i) = \|\mathbf{W}_{i,:,:,:}\|_F = \sqrt{\sum_{c,h,w} W_{i,c,h,w}^2}

Filtrni olib tashlashiibutun chiqish kanalini yo'q qiladi, FLOPlarni mutanosib ravishda kamaytiradi.

Lottery Ticket gipotezasi

Kichik yutuqli quyi tarmoq keng neyron panjara ichida ajratilgan

2019-yilda Frankle va Karbin Lotereya chiptalari gipotezasini (LTH) taqdim etdilar: tasodifiy ishga tushirilgan zich tarmoq ichida siyrak quyi tarmoq - "yutuq chiptasi" mavjud bo'lib, u asl ishga tushirilgandan so'ng o'rgatilgan bo'lib, taqqoslanadigan miqdordagi iteratsiyalar sonida to'liq tarmoqning aniqligiga mos keladi.

Rasmiy ravishda, o'ylab ko'ringf(x;θ0)f(\mathbf{x}; \boldsymbol{\theta}_0)bilan ishga tushirildiθ0Dθ\boldsymbol{\theta}_0 \sim \mathcal{D}_\theta. Konvergentsiyaga o'rgatgandan so'ng biz erishamizθ\boldsymbol{\theta}^*va Azizillo niqobini olingm\mathbf{m}. LTH borligini bildiradim\mathbf{m}shunday qilib:

f(x;mθ0)trainθmwhereacc(θm)acc(θ)f(\mathbf{x}; \mathbf{m} \odot \boldsymbol{\theta}_0) \xrightarrow{\text{train}} \boldsymbol{\theta}_m^* \quad \text{where} \quad \text{acc}(\boldsymbol{\theta}_m^*) \geq \text{acc}(\boldsymbol{\theta}^*)

bilanm0θ0\|\mathbf{m}\|_0 \ll |\boldsymbol{\theta}_0|. Dastlabki tajribalar MNIST va CIFAR-10 da boʻlib oʻtdi, bunda yutgan chiptalar parametrlarning 10-20 foizini saqlab qoldi. Bu haqda hech narsa faraz bo'yicha kitob ma'lumotlariga o'tkazilmaydi - LOB funktsiyalari statsionar emas va yorliq deyarli shovqin, bu muhim bo'lishi mumkin bo'lgan usullarda tasvir tasnifidan farq qiladigan rejim.

Iterativ magnituda pruningi (IMP)

Chipta IMP tomonidan topilgan:

  1. bilan tarmoqni ishga tushiringθ0\boldsymbol{\theta}_0.
  2. Konvergentsiyaga, olishga o‘rgatishθ\boldsymbol{\theta}^*.
  3. Kesishp%p\%eng kichik kattalikdagi og'irliklar, niqob yaratishm\mathbf{m}.
  4. Omon qolgan og'irliklarni o'z qiymatlariga qaytaringθ0\boldsymbol{\theta}_0(orqaga aylantirish).
  5. 2-bosqichdan boshlab niqoblangan tarmoq bilan takrorlang.

Har bir dumaloq qismni kesadipp(odatda 20%), shuning uchun keyinnnturlar(1p)n(1-p)^nparametrlari saqlanib qoladi. 10 raunddan keyinp=0.2p = 0.2, taxminan 10,7% qoldi.

Savdo modellari haqida tekshirilmagan uchta gipoteza

LTH ayniqsa bozor ma'lumotlarida yaxshi ishlashi kerakligi haqida bahslashish jozibali. Bunday uchta dalil keladi; uchtasi ham farazdir va ularni fakt sifatida ko'rsatish bu blogning oldini olish uchun mavjud bo'lgan muvaffaqiyatsizlik rejimidir.

  1. Moliyaviy signallar siyrak. Buyurtmalar kitobining aksar qismi shovqin, shuning uchun siyrak quyi tarmoq tabiiy ravishda siyrak signal bilan mos kelishi mumkin. Tekshirish mumkin: IMPni bir xil siyrak tasodifiy niqob bilan solishtiring; agar siyraklikning o'zi ishlayotgan bo'lsa, tasodifiy niqob orqada qolmasligi kerak.
  2. Yutilgan chiptalar rejimlar boʻyicha umumlashtiriladi. Bu hech qanday iqtibossiz bozorlar haqidagi empirik daʼvo boʻlib, uchtasi ichida eng qiziqarlisi. Bu to'g'ridan-to'g'ri HMMs bilan rejimni aniqlash dan rejim belgilariga qarshi sinovdan o'tkaziladi: A rejimidagi chiptani toping, uni B rejimida qayta o'qiting va B rejimida topilgan chipta bilan solishtiring.
  3. Sparsity regularizatsiya qiladi. Samarali sig‘imning pasayishi mikrostruktura shovqiniga moslashishni kamaytirishi mumkin — bu pruning qilingan modelning namunadan tashqari tafovuti zich modelnikidan kichikroq bo‘lishida, shunchaki unga teng bo‘lishida emas, ko‘rinadi.

Amalga oshirish: savdo MLPsini pruning qilish

Nerv qatlamlari aniq siyrak niqob orqali aylantirildi

Bazaviy model

import torch
import torch.nn as nn
import torch.nn.utils.prune as prune
from copy import deepcopy

class TradingMLP(nn.Module):
    """MLP for mid-price direction prediction from order book features."""
    def __init__(self, input_dim=100, hidden_dim=2048,
                 num_layers=4, output_dim=3):
        super().__init__()
        layers = []
        dims = [input_dim] + [hidden_dim] * (num_layers - 1) + [output_dim]
        for i in range(len(dims) - 1):
            layers.append(nn.Linear(dims[i], dims[i + 1]))
            if i < len(dims) - 2:
                layers.append(nn.BatchNorm1d(dims[i + 1]))
                layers.append(nn.ReLU())
                layers.append(nn.Dropout(0.1))
        self.network = nn.Sequential(*layers)

    def forward(self, x):
        return self.network(x)

    def count_parameters(self):
        return sum(p.numel() for p in self.parameters())

model = TradingMLP(input_dim=100, hidden_dim=2048,
                   num_layers=4, output_dim=3)
print(f"Total parameters: {model.count_parameters():,}")

Strukturaga kirmaydigan magnituda pruningi

def apply_unstructured_pruning(model, sparsity=0.9):
    """Apply global unstructured L1 pruning to all Linear layers."""
    parameters_to_prune = []
    for name, module in model.named_modules():
        if isinstance(module, nn.Linear):
            parameters_to_prune.append((module, 'weight'))

    prune.global_unstructured(
        parameters_to_prune,
        pruning_method=prune.L1Unstructured,
        amount=sparsity,
    )
    return model

def compute_sparsity(model):
    """Fraction of zero weights. Note: a *count*, not a speedup."""
    total, zeros = 0, 0
    for name, param in model.named_parameters():
        if 'weight' in name:
            total += param.numel()
            zeros += (param == 0).sum().item()
    return zeros / total if total > 0 else 0

pruned_model = apply_unstructured_pruning(deepcopy(model), sparsity=0.9)
print(f"Sparsity: {compute_sparsity(pruned_model):.1%}")

Strukturaviy pruning: natijani beradigan qayta qurish bilan

Qatorlarni maskalash - bu ishning yarmi. Tezlikni keltirib chiqaradigan yarmi har bir qatlamni qisqartirilgan shaklda tiklaydi - bu olib tashlashni oldinga yo'naltirishni anglatadi: qatorni tushirishjjqatlamdaniiustunni ham tushiradijjqatlamdani+1i+1va kanaljjhar qandayidanBatchNorm1dular orasida.

def apply_structured_pruning(model, fraction=0.75):
    """Mask entire neurons by L2-norm of their weight rows."""
    for name, module in model.named_modules():
        if isinstance(module, nn.Linear) and module.out_features > 10:
            prune.ln_structured(
                module, name='weight', amount=fraction, n=2, dim=0
            )
    return model

def rebuild_pruned_mlp(model):
    """
    Physically shrink a structurally pruned TradingMLP.

    Walks the Sequential once. For each Linear: drop the input columns
    the previous layer no longer emits, then drop its own dead output
    rows. BatchNorm1d channels follow the preceding Linear's survivors.
    """
    new_layers = []
    keep_in = None  # surviving output indices of the previous Linear

    for layer in model.network:
        if isinstance(layer, nn.Linear):
            if prune.is_pruned(layer):
                prune.remove(layer, 'weight')

            W, b = layer.weight.data, layer.bias.data
            keep_out = (W.norm(dim=1) > 0).nonzero(as_tuple=True)[0]
            W = W[keep_out]
            if keep_in is not None:
                W = W[:, keep_in]

            new = nn.Linear(W.shape[1], W.shape[0])
            new.weight.data = W.clone()
            new.bias.data = b[keep_out].clone()
            new_layers.append(new)
            keep_in = keep_out

        elif isinstance(layer, nn.BatchNorm1d):
            new = nn.BatchNorm1d(len(keep_in))
            new.weight.data = layer.weight.data[keep_in].clone()
            new.bias.data = layer.bias.data[keep_in].clone()
            new.running_mean = layer.running_mean[keep_in].clone()
            new.running_var = layer.running_var[keep_in].clone()
            new.num_batches_tracked = layer.num_batches_tracked.clone()
            new_layers.append(new)

        else:  # ReLU, Dropout -- shape-agnostic, reuse as is
            new_layers.append(layer)

    rebuilt = deepcopy(model)
    rebuilt.network = nn.Sequential(*new_layers)
    return rebuilt

Bunga ishonishdan oldin ikkita narsani tekshirish kerak, blogning qolgan qismi ekvivalentlik eshiklari bilan bir xil ruhda ishlaydi:

  • Shakllar.rebuiltda yashirin o'lchamlarni ko'rsatishi kerak(1fraction)h(1 - \text{fraction}) \cdot h- 512 uchunfraction=0.75, h=2048h = 2048- va ichki matritsalarning ikkala o'lchami qisqarganligi sababli kvadratik ravishda tushgan parametrlar soni.
  • Chiqishlar. Ineval()rejim,rebuilt(x)niqoblangan modelga mos kelishi kerakrebuilt-bir partiyada suzuvchi nuqta bardoshliligiga bepul chiqish. Agar shunday bo'lmasa, ustunning tarqalishi noto'g'ri va har bir quyi oqim soni siz o'ylaganingizdan boshqa modelni o'lchaydi.

Qatorda omon qolish testi niqoblangan qatorni aniq nolga teng, jonli qator esa nolga teng deb taxmin qiladi. Bu amal qiladiln_structuredchiqish; Agar boshqa protsedura haqiqiy nolga teng jonli neyron ishlab chiqargan bo'lsa, bu bajarilmaydi, shuning uchun me'yor testiga ko'r-ko'rona ishongandan ko'ra, omon qolganlar sonini so'ralgan fraktsiyaga nisbatan tasdiqlang.

Iterativ magnituda pruningi (Lottery Ticket qidiruvi)

def lottery_ticket_search(model_cls, model_kwargs, train_fn, eval_fn,
                          rounds=10, prune_rate=0.2, device='cpu'):
    """
    Iterative Magnitude Pruning to find a winning ticket.

    Parameters
    ----------
    model_cls : class -- model constructor
    model_kwargs : dict -- constructor arguments
    train_fn : callable -- train_fn(model) trains the model in-place
    eval_fn : callable -- eval_fn(model) returns out-of-sample accuracy
    rounds : int -- number of pruning rounds
    prune_rate : float -- fraction of surviving weights pruned per round
    """
    model_init = model_cls(**model_kwargs).to(device)
    theta_0 = deepcopy(model_init.state_dict())

    mask = {}
    for name, param in model_init.named_parameters():
        if 'weight' in name:
            mask[name] = torch.ones_like(param, dtype=torch.bool)

    results = []

    for round_idx in range(rounds):
        model = model_cls(**model_kwargs).to(device)
        state = deepcopy(theta_0)
        for name in mask:
            state[name] = state[name] * mask[name].float()
        model.load_state_dict(state)

        train_fn(model)

        acc = eval_fn(model)
        surviving = sum(m.sum().item() for m in mask.values())
        total = sum(m.numel() for m in mask.values())
        sparsity = 1.0 - surviving / total

        results.append({
            'round': round_idx,
            'accuracy': acc,
            'sparsity': sparsity,
            'surviving_params': int(surviving)
        })
        print(f"Round {round_idx}: acc={acc:.4f}, "
              f"sparsity={sparsity:.1%}")

        all_weights = []
        for name, param in model.named_parameters():
            if name in mask:
                alive = param.data.abs()[mask[name]]
                all_weights.append(alive.flatten())

        all_weights = torch.cat(all_weights)
        k = int(len(all_weights) * prune_rate)
        if k == 0:
            break
        threshold = all_weights.kthvalue(k).values.item()

        for name, param in model.named_parameters():
            if name in mask:
                mask[name] = mask[name] & (
                    param.data.abs() >= threshold
                )

    return results, mask

resultsbu maqola sizga qarzdor bo'lgan siyraklik-aniqlik egri chizig'i uchun xom ashyo hisoblanadi.eval_fnHaqiqatan ham namunadan tashqarida bo'lishi kerak, tozalangan bo'linishlarda - namunadagi ball to'plangan IMP ishlashi hech narsani anglatmaydigan chiroyli egri chiziq haqida xabar beradi.

Uni o‘lchash

Mavhum samaradorlik chegarasini muvozanatlash, siyraklik aniqligi va kechikish

Kechikish blogning qolgan qismidagi kabi bir xil jihozlar konventsiyasi bilan o'lchanadi - isinish chiqarib tashlandi, eng yaxshi N, o'rtacha emas, p50/p95/p99 xabar qilindi - va bu protokol kod bilan Polars vs pandas. Azizillo uchun uchta nuqta:

  • Niqoblangan modelni emas, qayta qurilgan modelni taqqoslang. Partiya o'lchami 1da niqoblangan model zich shaklni o'lchaydi.
  • Partiya hajmi haqida xabar bering. 1-to'plam (iqtiboslar davri) va 256-to'plam (tadqiqotni tekshirish) xotiraga bog'langan/hisoblash bilan bog'langan chiziqning turli tomonlarida joylashgan va kesish ularga boshqacha yordam beradi.
  • Yorliq ta’rifi ko‘rsatilgan holda, bir xil bo‘linishda va bir xil gorizontda aniqlikni hisobot qiling. Mos aniqlik ustunisiz kechikish jadvali modelni butunlay o‘chirish uchun dalil bo‘ladi.

Ilg‘or texnikalar

Kengaytirilgan tarmoqni siqish yoʻllari bitta samarali modelga birlashadi

Bilimlarni distillash bilan pruning

Alohida ravishda kesish va nozik sozlash o'rniga, o'qituvchi sifatida asl zich modeldan foydalaning. Kesilgan talaba vazifani yo'qotish va o'qituvchining mahsulot taqsimotidan KL farqini minimallashtiradi:

L=(1α)Ltask(y,y^s)+αT2DKL(σ(ztT)σ(zsT))\mathcal{L} = (1 - \alpha) \cdot \mathcal{L}_{\text{task}}(\mathbf{y}, \hat{\mathbf{y}}_s) + \alpha \cdot T^2 \cdot D_{\text{KL}}\left(\sigma\left(\frac{\mathbf{z}_t}{T}\right) \| \sigma\left(\frac{\mathbf{z}_s}{T}\right)\right)

bu yerda zt\mathbf{z}_t va zs\mathbf{z}_s — o‘qituvchi va talaba logitlari, TT — harorat, α\alpha esa maqsadlarni muvozanatlashtiradi. T2T^2 koeffitsiyenti distillash gradientlarini qayta masshtablaydi; aks holda ular 1/T21/T^2 ga mutanosib ravishda kichrayadi.

def distillation_loss(student_logits, teacher_logits, labels,
                      temperature=3.0, alpha=0.5):
    """Combined task + distillation loss."""
    task_loss = nn.CrossEntropyLoss()(student_logits, labels)

    soft_student = nn.functional.log_softmax(
        student_logits / temperature, dim=-1
    )
    soft_teacher = nn.functional.softmax(
        teacher_logits / temperature, dim=-1
    )
    kd_loss = nn.functional.kl_div(
        soft_student, soft_teacher, reduction='batchmean'
    )

    return (1 - alpha) * task_loss + alpha * (temperature ** 2) * kd_loss

Harakat bo‘yicha pruning

Mutlaq kattalik bilan kesish o'rniga, harakatni kesish (Sanh va boshq., 2020) mashg'ulot paytida nolga qarab harakatlanadigan og'irliklarni kesadi. Muhimlik ko'rsatkichi gradient og'irligi mahsulotini to'playdi:

Sij(t)=Sij(t1)+Wij(t)Wij(t1)sign(Wij(t)LWij(t))S_{ij}^{(t)} = S_{ij}^{(t-1)} + \left| W_{ij}^{(t)} - W_{ij}^{(t-1)} \right| \cdot \text{sign}\left(W_{ij}^{(t)} \cdot \frac{\partial \mathcal{L}}{\partial W_{ij}^{(t)}}\right)

Salbiy ballga ega bo'lgan vaznlar kesiladi. Kattalik Azizillo bo'yicha argument aynan nozik sozlash bilan bog'liq: siz oldindan o'rgatilgan modelni moslashtirganingizda, kattalik taqsimoti mashg'ulotdan oldingi topshiriq bilan shakllantiriladi, shuning uchun kattalik eskirgan muhim signaldir va sayohat yo'nalishi yangiroqdir. Deraza oynalarida qayta o'qitilgan savdo modeli uchun bu noldan mashq qilishdan ko'ra keng tarqalgan holat.

NVIDIA 2:4 strukturaviy siyraklik

Amperli va keyingi NVIDIA GPUlari apparatdagi 2:4 tuzilgan siyraklikni qo‘llab-quvvatlaydi: har 4 ta qo‘shni og‘irlikdan aynan 2 tasi nolga teng bo‘lishi kerak.

i,W[4i:4i+4]0=2\forall i, \quad \|\mathbf{W}_{[4i:4i+4]}\|_0 = 2

Bu nozik taneli siyraklikning bir ko'rinishi bo'lib, uni apparat haqiqatda mukofotlaydi, shuning uchun bu tuzilmagan Azizillo natijasida 90% noldan ko'proq ahamiyatga ega. Cheklov global emas, mahalliy - har to'rttasidan ikkitasi omon qolishi unga ahamiyat bermaydi - shuning uchun bu global niqobni o'rnatishdan ko'ra ancha zaifroq cheklovdir, garchi 50% taklif qilinadigan yagona kamlik darajasidir.

from torch.ao.pruning import WeightNormSparsifier

sparsifier = WeightNormSparsifier(
    sparsity_level=0.5,
    sparse_block_shape=(1, 4),
    zeros_per_block=2,
)

sparsifier.prepare(
    model, config=[{"tensor_fqn": "network.0.weight"}]
)
sparsifier.step()
sparsifier.squash_mask()

Tezlikni amalga oshirish siyrak tensor yadrolaridan foydalanish uchun xulosa chiqarish yo'lini talab qiladi - ONNX eksporti va TensorRT tuzilishi yokitorch.sparse.to_sparse_semi_structured. 2:4 maskeli modelni zich ish vaqti orqali eksport qilish sizga aniqlik narxini beradi va hech qanday foyda keltirmaydi.

Ishlab chiqarishga joylashtirish

Kichik kechikishli apparat kanaliga kiruvchi oddiy xulosa modeli

Validatsiya

Kesilgan model siqilgan eski emas, yangi model bo‘lib, u boshqa nomzodlar kabi qabul qilish eshigidan o‘tadi: qayta o‘qitish va namunadan tashqari qayta tekshirish oldinga optimallashtirish, oʻchirilgan Sharpe nisbati dan tanlash effekti tuzatish bilan. Bu tuzatish ixtiyoriy emas - IMP nomzod modellarining ketma-ketligini hosil qiladi, shuning uchun o'n raund bo'yicha eng yaxshi ko'rinadigan siyraklik darajasi qidiruv ostida tanlandi va uning Sharpe samarali sinovlar soni bo'yicha deflatsiya qilinishi kerak. "Sharpe 5% dan ko'proq tushsa, rad etish" kabi tekis qoida bu arifmetikadan omon qolmaydi, shuning uchun siz ushbu maqolada uni topa olmaysiz.

Kvantlashni stacking qilish

Azizillo kvantlash bilan tuzadi. 90% siyrak va INT8 ga kvantlangan model quyidagi siqilish nisbatiga ega:

CR=1(1s)boriginalbquantized=10.1328=40×\text{CR} = \frac{1}{(1 - s)} \cdot \frac{b_{\text{original}}}{b_{\text{quantized}}} = \frac{1}{0.1} \cdot \frac{32}{8} = 40\times

48 MB hajmli model 1,2 MB ga aylanadi. Bu faqat saqlash haqidagi da’vo. 1,2 MB model bir xil qarorlarni chiqaradimi — bu alohida savol; GPU aniqligi bunga sabab: bu blogda fp32ning o‘zi mantiqan to‘g‘ri ko‘ringan backtest hisobida nisbiy xatoni 211 ga yetkazgani ko‘rsatilgan. INT8 bundan ancha agressiv qisqartirishdir. Kvantlangan va pruning qilingan modelni fp32 zich modeliga nisbatan o‘lchangan parity gate ortidagina joylashtiring — ushlab turilgan davrdagi qarorlar mosligi va PnL farqi kafolat emas, o‘lchov bo‘lsin.

Monitoring va kuzatuv

Kesilgan modellar tarqatish siljishiga nisbatan sezgir bo'lishi mumkin. Ko'rishga arziydi:

  • Aktivatsiyaning siyrakligi: agar tirik qolgan neyronlar asosan nol chiqaradigan bo'lsa, samarali model mo'ljallanganidan kichikroq va ehtimol yomonlashadi.
  • Qayta tayyorlash vaqtidagi gradient normalari: portlovchi gradientlar omon qolgan quyi tarmoqdan olib tashlangan narsa uchun juda agressiv kompensatsiya talab qilinishini ko‘rsatadi.
  • Entropiyani bashorat qilish: shovqinli mikrotuzilma ma'lumotlariga haddan tashqari ishonadigan kesilgan model, ehtimol, mashg'ulot rejimiga mos keladi.

Xulosa

Kuchli noaniqlikdan hal qiluvchi ixcham samarali neyron tarmoq

Usullar yaxshi o'rnatilgan va tozalash tugaguniga qadar, bu maqolada aytilishicha. Tarkibi bo'lmagan Azizillo sizga siyrak raqam va tezlikni bermaydi. Strukturaviy Azizillo qatlamlarni niqoblash o'rniga ularni qayta tiklasangiz, sizga tezlikni beradi. Lotereya chiptalari gipotezasi ixcham modelning haddan tashqari parametrlangan modelda allaqachon mavjudligini ko'rsatadi, garchi bu buyurtmalar kitobi ma'lumotlarida emas, balki tasvir mezonlarida namoyish etilgan va yuqorida keltirilgan bozor ma'lumotlarida "ishlashi" kerak bo'lgan uchta sabab - bu topilmalar emas, balki tajribalar biriktirilgan gipotezalar.

Adabiyotdagi amaliy evristik usul boshidanoq dizaynni kichikroq qilishdan ko'ra katta va kesishni o'rgatishdir: katta model yo'qotish landshaftini samaraliroq o'rganadi va kesish muhim bo'lgan yo'llarni saqlaydi. Bu savdo modeli uchun mos keladimi, qanday siyraklik va qanday aniqlik narxi, bir IMP supurgi hisoblanadi - va ushbu maqolani o'sha supurishdan keyin raqamlar bilan yana o'qish kerak.

blog.disclaimer

Authors

Eugen Soloviov
Eugen Soloviov

Trading-systems engineer

Trading-systems engineer building bots since 2017: cross-exchange arbitrage (connected up to 30 venues), cointegration-based pairs arbitrage across spot and futures, scalping, news and sentiment-driven strategies, trend algorithms, and portfolio management and balancing algorithms. Also builds sub-millisecond order execution, big-data warehouses, backtesting engines, AI agents, and trading interfaces (incl. open-source profitmaker.cc). Stack: JS/TS, Python, Rust/Zig/Go, DevOps, backend, frontend, architecture.

Newsletter

Bozordan bir qadam oldinda bo'ling

Sun'iy intellekt savdo tahlillari, bozor tahlili va platforma yangiliklari uchun bizning xabarnomaga obuna bo'ling.

Biz sizning maxfiyligingizni hurmat qilamiz. Istalgan vaqtda obunadan chiqishingiz mumkin.