← На главную

Хаб курсов / LLM Inference Systems / глава 13

Модуль 13: KV-хэндофф: передача кеша между моделями и узлами

PD-дизагрегация, RDMA-транспорт (Thunderbolt, ConnectX), перенос кэша внутри семейства (ridge-маппер, CacheBridge) и между семействами (SwaT). Симулятор хэндоффа и ridge-маппер на numpy.

LLM Inference Systems. Модуль 13: KV-хэндофф: передача кеша между моделями и узлами

KV-кэш — это не служебный объект внутри одного процесса, а полновесный артефакт: на Qwen3-8B при контексте 32k в fp16 он весит 4.5 ГиБ (расчёт из модуля 04: 2·36·8·128·2 = 144 КиБ/токен × 32768). Пока кэш привязан к узлу, где случился prefill, каждая смена модели или машины заставляет получателя платить prefill заново — полный проход весов по всему контексту. Этот модуль — про то, как передать готовый кэш вместо повторного вычисления: между датацентрами (PD-дизагрегация за пределами одного RDMA-домена), между машинами на бытовом транспорте (RDMA поверх Thunderbolt), и — самое неожиданное — между разными моделями, включая разные семейства, через обучаемый линейный маппинг.

Prefill-кластер передаёт сжатый KV-кэш decode-кластеру по RDMA вместо повторного префилла

Экономика проста: prefill при контексте n делает 2Nn FLOP (для 8B на 25k токенов — 4×10¹⁴ FLOP, десятки секунд на одной GPU), а передача кэша ограничена только полосой канала. Если канал гоняет 23.9 ГБ/с (четыре кабеля Thunderbolt), 1.1 ГиБ кэша int8 на 25k контексте (144 КиБ/токен ÷ 2 × 25000 ÷ 2⁵⁰... см. расчёт в разделе 1) доедет за доли секунды. Выигрыш по TTFT — от 2.7× до 25× по данным статьи про cross-model transfer. Но у передачи кэша есть цена: маппинг между моделями не идеален (73–98% retention качества у линейного маппера, 99.83% у CacheBridge, честные 90–110% у cross-family SwaT), и часть модуля — про то, как эти проценты измерять, а не принимать на верву.

1. Арифметика: когда кэш дешевле, чем prefill

Формула размера кэша из модуля 04:

\text{KV bytes} = 2 \cdot L \cdot H_{kv} \cdot d_{head} \cdot n_{ctx} \cdot b

Для Qwen3-8B (36 слоёв, 8 KV-голов, d_head = 128, fp16 = 2 байта) это 144 КиБ/токен. Посчитаем транспортную задачу: контекст 25 000 токенов.

  • fp16: 144 КиБ × 25000 = 144 × 1024 × 25000 = 3 686 400 000 байт ≈ 3.43 ГиБ (расчёт).
  • int8/fp8 (b = 1): ровно вдвое меньше — 1.72 ГиБ (расчёт; квантование KV — модуль 04, раздел 5.1).

Теперь сравним два способа передать 25k-контекст получателю.

Повторный prefill. FLOP префилла ≈ 2Nn: для 8B-модели (N ≈ 8.2×10⁹) на 25k токенов — 2 × 8.2e9 × 25000 = 4.1×10¹⁴ FLOP. На GPU с ~990 ТФЛОП/с fp16 и утилизацией 40–60% (модуль 04) это примерно 0.7–1.0 с чистой арифметики, но на слабом decode-узле (например, инференс-карта с 100 ТФЛОП/с) — уже 4–8 секунд. И это compute-bound задача: узлу нужен не bandwidth, а тензорные ядра.

Передача кэша. Тот же объём как данные: 1.72 ГиБ int8.

каналполосавремя передачи 1.72 ГиБэквивалентный prefill-выигрыш на слабом узле
25 GbE3.1 ГБ/с~0.55 с7–14×
100 GbE12.5 ГБ/с~0.14 с30–60×
4× TB MCDMA23.9 ГБ/с~0.07 с60–120×

(колонка «время» — расчёт: объём / полоса; «выигрыш» — относительно 4–8 с prefill на слабом узле, оценка.)

Вывод, который стоит держать в голове: отношение полосы канала к скорости префилла получателя — единственная переменная, которая решает, выгоден ли хэндофф. Если получатель — H100, prefill 25k займёт меньше секунды, и гонять 1.72 ГиБ по 25 GbE нет смысла. Если получатель — laptop GPU или decode-кластер, куда prefill-мощность сознательно не ставили, — хэндофф выигрывает на порядках.

Порог «переносить vs пересчитывать» на практике. Правило принятия решения подтверждено прод-практикой PD-дизагрегации: перенос KV-кэша оправдан, когда remote prefill + transfer < local prefill — то есть когда стоимость префилла на префилл-узле плюс время транспорта по каналу меньше, чем префилл того же контекста на узле-получателе. Для моделей 70B+ с длинными промптами и каналом класса IB это условие выполняется почти всегда: префилл 70B+ на длинном контексте стоит секунды, а перенос гигибайтов кэша по IB — десятки миллисекунд. Обратная сторона: bottleneck KV-трансфера на PCIe в прод-масштабе по состоянию на апрель 2026 (arXiv) не решён — когда кэш гоняется не по сети, а между GPU и host внутри узла, именно PCIe-копирование становится доминирующей частью хэндоффа, и универсального лекарства до сих пор нет.

2. PD-дизагрегация за пределами одного кластера: PrfaaS

Классическая PD-дизагрегация (модуль 10, Mooncake, DistServe) разделяет prefill- и decode-узлы, но держит их в одном низколатентном RDMA-домене — потому что кэш надо передавать быстро и предсказуемо. Статья Prefill-as-a-Service (arXiv 2604.15039) задаёт вопрос: что если prefill вынести вообще в другой датацентр?

Проблема не в размере кэша как таковом. Гибридные архитектуры внимания (модуль 04: sliding-window, MLA) уже сжали кэш — DeepSeek-MLA хранит 68.6 КиБ/токен против 144 у Qwen3-8B. Оставшиеся четыре проблемы из текста статьи:

  1. Бурстность трафика — поток запросов неравномерен, канал простаивает или перегружается.
  2. Скошенность длин — запросы на 200 и на 25k токенов стоят канала по-разному.
  3. Неравномерность prefix-кэшей — кэшированные префиксы лежат там, где их не ждут.
  4. Флуктуации межкластерной полосы — commodity Ethernet не даёт предсказуемого RDMA-сервиса.

Наивное «вынесем весь prefill наружу» даёт заторы и нестабильные очереди. PrfaaS отвечает тремя механизмами:

  • Селективный оффлоад — наружу уходят только длинные контексты (те, где префилл дорог, а кэш на токен окупается); короткие считаются локально.
  • Bandwidth-aware scheduling — планировщик знает текущую полосу межкластерного линка и не ставит в очередь больше байт, чем канал проглотит за разумное время.
  • Cache-aware request placement — запрос направляется в тот кластер, где уже лежит его префикс-кэш, а не в свободнейший.

Цифры статьи (внутренняя гибридная модель 1T параметров): связка PrfaaS даёт на 54% выше throughput, чем гомогенный PD, и на 32% выше, чем наивная гетерогенная дизагрегация, — при скромном расходе межкластерной полосы. Архитектурный итог: prefill- и decode-ёмкости масштабируются независимо и по разному железу, потому что исчезает требование общего RDMA-фабрика.

3. Транспорт: когда память перестаёт быть узким местом

Два инженерных сюжета про транспорт на «недатацентровом» железе — какие цифры здесь ни приводи, это замеры авторов, не независимые.

MCDMA — RDMA поверх Thunderbolt. Идея: Thunderbolt — это PCIe-туннель, а по PCIe можно гонять RDMA без ядра сетевого стека. Архитектура: до четырёх TB-кабелей между машинами, суммарно 23.9 ГБ/с, RTT около 8 мкс. Это полоса уровня 200 GbE-класса на кабелях за сотни рублей и без коммутатора. Ограничение архитектурное: TB-цепочка точка-точка, дальность и топология жёсткие (дерево/цепочка, не сплетня).

MelonDMA — Mellanox/NVIDIA ConnectX через DriverKit. macOS исторически не даёт писать kernel-расширения для сетевок; DriverKit — user-space фреймворк драйверов. MelonDMA поднимает RDMA-транспорт на ConnectX из user space, получая RDMA-сервис там, где раньше был только kqueue/TCP. Это ставит Mac-кластеры в один транспортный класс с Linux-нодами по RDMA.

Общий вывод обоих сюжетов: узкое место смещается с памяти на планирование. Когда полоса между машинами измеряется десятками ГБ/с, а RTT — микросекундами, стоимость передачи кэша становится сопоставимой с копированием внутри одной машины, и вопрос «где что считать» превращается из компромисса в свободный выбор.

4. Same-family: closed-form маппинг KV между размерами модели

Самый контринтуитивный результат курса. Кэш модели A бесполезен модели B — другой набор весов порождает другие активации. Статья arXiv 2608.03893 показывает: внутри семейства кэши связаны линейно.

Эмпирика на Qwen3 14B→32B: одна исходная карта (layer) объясняет 56% дисперсии ключей целевой модели и 32% значений; несколько исходных карт поднимают это до 79% и 65%. Отсюда конструкция:

  1. Per-head ridge-маппер: для каждой целевой карты выбирается top-k наиболее предсказательных исходных карт, их KV конкатенируются во вход регрессии.
  2. Strip-RoPE: RoPE-фазу с ключей снимают до маппинга — фаза зависит от позиции, и регрессия, подогнанная на абсолютных координатах, не перенесётся на другую длину контекста. Без фазы подгонка position-free и переиспользуется на любом контексте.
  3. Калибровка: 500 последовательностей FineWeb-Edu по 1024 токена — закрытая форма ridge-регрессии, без градиентов.

Результаты: на шести парах в трёх семействах линейный маппер сохраняет 73–98% accuracy самостоятельного префилла получателя на четырёх парах; две пары деградируют резко (нелинейный MLP вытягивает до +37 pp HellaSwag на неудачных). Маппер работает в 2.7–25× быстрее повторного префилла и стабилен на многотурновом хэндоффе.

CacheBridge (arXiv 2609.00891) чинит слабые места Full-Head Mapping:

  • Head-матчинг вместо полного перекрёстного маппинга: каждой целевой голове — одна согласованная исходная, поддержка маппера индексируется архитектурой. Хранение маппера на Qwen3 14B→32B падает в 8×, применение ускоряется до 3.0×.
  • Взвешивание ошибок по каузальной чувствительности внимания + fused-ядро, не материализующее полные тензор наблюдений.
  • Retention 99.83% на Qwen3; вытягивает два направления Ministral 3, где полный маппинг терял качество; калибровки нужно в 10 раз меньше; сборка маппера на 500 последовательностях падает с 92.63 до 8.63 с — 10.7×.

5. Cross-family: SwaT и честная арифметика retention

Swarm Telepathy (arXiv 2610.15095) — первый метод передачи кэша между семействами (6 семейств, 12 моделей, 17 бенчмарков). Обучаемый маппинг, обе модели заморожены, обучение — <50M токенов и <1 GPU-дня. В связке с компакцией кэша агент-агент коммуникация через SwaT даёт в среднем +40% accuracy и 4× быстрее по wall-clock, чем обмен текстом.

Честная оговорка (и это главный урок модуля): сама по себе передача кэша через SwaT даёт retention 90–110% от baseline «получатель сделал свой prefill» — то есть в среднем уровень паритета, не выигрыш. Разброс по парам большой — 31–99%. Выигрыш +40%/4× возникает только в связке с компакцией: сжатый кэш несёт меньше токенов, получатель экономит и на префилле, и на памяти, а качество сохраняется лучше, чем при сжатии текстовой перефразировкой. Нельзя цитировать +40% как эффект маппинга — это эффект системы маппинг+компакция против текстового протокола.

6. Что это значит для инженера

сценарийметодключевая цифраисточник
prefill в чужом ДЦPrfaaS селективный оффлоад+54% throughput vs гомогенный PD2604.15039
кластер на Mac/десктопеMCDMA (4×TB)23.9 ГБ/с, RTT ~8 мксзамеры авторов
смена размера модели в семьеridge-маппер + strip-RoPE73–98% retention, 2.7–25× быстрее префилла2608.03893
то же, productionCacheBridge99.83% retention, маппер −8× storage, сборка 10.7× быстрее2609.00891
разные семействаSwaT + компакция90–110% retention сам по себе; +40%/4× со сжатием2610.15095

Правила принятия решения (проверяйте по чеклисту ниже, каждый пункт считается, а не оценивается на глаз):

  1. Считайте байты до выбора метода. 2·L·H_kv·d_head·b на токен — если кэш int8 на вашем контексте весит меньше, чем секунда полосы канала, а prefill получателя дороже секунды — хэндофф выгоден.
  2. Strip-RoPE — обязательный шаг любого межмодельного маппинга ключей. Регрессия на фазе не переносится между контекстами.
  3. Retention меряйте на своём распределении. 73–98% — это шесть пар трёх семейств на стандартных бенчмарках; ваша пара моделей может оказаться в «двух деградировавших».
  4. Межсемейство — не замена префиллу, а часть пайплайна со сжатием. Паритет 90–110% сам по себе; выигрыш даёт только композиция.

Задание 13.1. Симулятор хэндоффа: TTFT против baseline

Цель. Смоделировать на numpy сценарий «умная модель строит сжатый кэш, дешёвая принимает его без prefill» и замерить выигрыш по TTFT в матрице «контекст × битрейт кэша × канал».

Модель задержек (все величины — расчёт по формулам, не эмпирика):

  • Prefill получателя: t_prefill = 2·N·n / F, где F — эффективные FLOP/с получателя.
  • Хэндофф: t_tx = KV_bytes / BW + t_map (применение маппера, считается как пропускная способность маппера в байтах/с × объём кэша).
  • TTFT_hybrid = t_tx + t_map; TTFT_baseline = t_prefill.

Матрица: контексты {4k, 16k, 64k}, битрейты кэша {fp16: 2 б, int8: 1 б, int4: 0.5 б}, каналы {25 GbE: 3.1 ГБ/с, 100 GbE: 12.5 ГБ/с, TB4: 23.9 ГБ/с}. Получатель — слабый decode-узел: 100 ТФЛОП/с (типичная консюмерская/инференс-карта, оценка).

Задание 13.2. Ridge-маппер KV между двумя размерами toy-архитектуры

Цель. Повторить пайплайн 2608.03893 на игрушечных моделях со случайными весами: strip RoPE, per-head ridge, замер R² и retention-прокси. Принцип тот же, число голов KV и d_head у обеих моделей совпадают (условие применимости closed-form подхода из статьи: source и target делят KV head count и per-head dim).

Код

"""module13.py — KV-ХЭНДОФФ: арифметика передачи кэша, симулятор TTFT,
ridge-маппер KV между двумя размерами toy-архитектуры.

Запуск:
    python module13.py            # все части
    python module13.py sim        # только симулятор 13.1
    python module13.py mapper     # только ridge-маппер 13.2

Только numpy, CPU. Никаких сетей и весов реальных моделей.
"""
import sys
import numpy as np

rng = np.random.default_rng(13)

# ---------------------------------------------------------------- конфиги
# Реальные конфиги Qwen3 (модуль 04): (слои, KV-головы, head_dim)
QWEN3_8B = dict(L=36, H_kv=8, d_head=128)

# Каналы: полоса в байтах/с
CHANNELS = [
    ("25GbE", 3.1e9),
    ("100GbE", 12.5e9),
    ("4xTB4 (MCDMA)", 23.9e9),
]
DTYPES = [("fp16", 2), ("int8", 1), ("int4", 0.5)]
CONTEXTS = [4096, 16384, 65536]


# ------------------------------------------------- часть 1: арифметика байт
def kv_bytes_per_token(cfg, b):
    """Байт/токен: 2 * L * H_kv * d_head * b (модуль 04)."""
    return 2 * cfg["L"] * cfg["H_kv"] * cfg["d_head"] * b


def prefill_flops(n_params, n_ctx):
    """FLOP префилла ~ 2*N*n (модуль 04: интенсивность n FLOP/байт)."""
    return 2 * n_params * n_ctx


def sim_ttft():
    """Задание 13.1: матрица контекст x битрейт x канал -> выигрыш TTFT."""
    # Слабый decode-узел: 100 TFLOP/с fp16 (оценка, не из статей)
    F_receiver = 100e12
    N_receiver = 8.2e9          # 8B-параметров получатель
    b_bytes_per_flop = 2        # fp16 веса: 2 байта на параметр — не влияет на FLOP-модель

    print("== Задание 13.1: TTFT hybrid (tx+map) vs baseline (prefill), Qwen3-8B KV ==")
    print(f"получатель: {N_receiver/1e9:.0f}B, {F_receiver/1e12:.0f} TFLOP/с\n")

    for n_ctx in CONTEXTS:
        t_prefill = prefill_flops(N_receiver, n_ctx) / F_receiver
        print(f"контекст {n_ctx}: baseline prefill = {t_prefill*1000:.0f} мс")
        for dtype, b in DTYPES:
            size = kv_bytes_per_token(QWEN3_8B, b) * n_ctx
            for ch_name, bw in CHANNELS:
                t_tx = size / bw
                # применение маппера: линейная модель, ~ чтение+запись кэша,
                # оцениваем 1 ТБ/с эффективной обработки (память узла, оценка)
                t_map = size / 1e12
                ttft = t_tx + t_map
                speedup = t_prefill / ttft
                print(f"  {dtype:>5} {size/2**30:6.2f} ГиБ | {ch_name:<14} "
                      f"tx {t_tx*1000:7.1f} мс | TTFT {ttft*1000:7.1f} мс | x{speedup:6.1f}")
        print()


# ------------------------------------------- часть 2: toy-модель и маппинг
def rope_cache(n_ctx, d_head):
    inv = 1.0 / (10000.0 ** (np.arange(0, d_head, 2) / d_head))
    t = np.arange(n_ctx)
    freqs = np.outer(t, inv)                    # [n_ctx, d_head/2]
    return np.cos(freqs), np.sin(freqs)


def apply_rope(x, cos, sin, pos):
    """x: [T, H, d_head]; RoPE на парах (0,1),(2,3),..."""
    x1, x2 = x[..., 0::2], x[..., 1::2]
    c = cos[pos][:, None, :]  # [T, 1, d/2]
    s = sin[pos][:, None, :]
    r1 = x1 * c - x2 * s
    r2 = x1 * s + x2 * c
    out = np.empty_like(x)
    out[..., 0::2], out[..., 1::2] = r1, r2
    return out


def strip_rope(x, cos, sin, pos):
    """Обратная операция: снять фазу (RoPE — вращение, обратимо)."""
    x1, x2 = x[..., 0::2], x[..., 1::2]
    c = cos[pos][:, None, :]
    s = sin[pos][:, None, :]
    r1 = x1 * c + x2 * s
    r2 = -x1 * s + x2 * c
    out = np.empty_like(x)
    out[..., 0::2], out[..., 1::2] = r1, r2
    return out


def make_toy_model(seed, L, H_kv, d_head, d_model):
    """Случайные веса; 'родство' моделей создаём так: target = source + шум,
    что даёт реалистичную линейную связь активаций, как в 2608.03893."""
    r = np.random.default_rng(seed)
    Wq = r.normal(0, 1 / np.sqrt(d_model), (L, d_model, H_kv * d_head))
    # target-модель: те же веса + возмущение (имитация внутри семейства)
    noise_scale = 0.35
    return dict(Wq=Wq, noise=noise_scale, L=L, H_kv=H_kv, d_head=d_head,
                d_model=d_model, seed=seed)


def kv_cache_of_layer(model, layer, x, cos, sin):
    """K для одного слоя без внимания: K = x @ Wq[layer]; [T, H_kv, d_head]."""
    Wq = model["Wq"][layer]
    k = x @ Wq                                   # [T, H_kv*d]
    k = k.reshape(len(x), model["H_kv"], model["d_head"])
    return k


def fit_ridge_per_head(X, Y, lam=1e-2):
    """X: [T, H, dx], Y: [T, H, dy] -> W [H, dx, dy] (закрытая форма ridge)."""
    T, H, dx = X.shape
    dy = Y.shape[-1]
    W = np.empty((H, dx, dy))
    for h in range(H):
        Xh, Yh = X[:, h, :], Y[:, h, :]
        A = Xh.T @ Xh + lam * np.eye(dx)
        W[h] = np.linalg.solve(A, Xh.T @ Yh)
    return W


def r2_per_head(pred, true):
    """R^2 по головам: 1 - SSE/SST (по признаковым координатам)."""
    num = ((pred - true) ** 2).sum(axis=(0, 2))
    den = ((true - true.mean(axis=0, keepdims=True)) ** 2).sum(axis=(0, 2))
    return 1 - num / den


def run_mapper():
    """Задание 13.2: ridge-маппер K между toy-моделями, strip-RoPE vs нет."""
    L, H_kv, d_head, d_model = 6, 4, 32, 128
    n_ctx = 512
    src = make_toy_model(1, L, H_kv, d_head, d_model)
    tgt = make_toy_model(2, L, H_kv, d_model=d_model, d_head=d_head)
    # связываем: возмущаем исходные веса (внутрисемейное сходство)
    r = np.random.default_rng(3)
    tgt["Wq"] = src["Wq"] + r.normal(0, 0.35, src["Wq"].shape)

    cos, sin = rope_cache(n_ctx, d_head)
    x = rng.normal(0, 1, (n_ctx, d_model))
    pos = np.arange(n_ctx)

    n_cal = 384                                   # калибровка (статья: 500 секв.)
    results = {}
    for mode in ("raw", "stripped"):
        R2 = np.zeros((L, H_kv))
        for layer in range(L):
            Ks = kv_cache_of_layer(src, layer, x, cos, sin)
            Kt = kv_cache_of_layer(tgt, layer, x, cos, sin)
            if mode == "stripped":
                Ks = strip_rope(Ks, cos, sin, pos)
                Kt = strip_rope(Kt, cos, sin, pos)
            W = fit_ridge_per_head(Ks[:n_cal], Kt[:n_cal])
            pred = np.einsum("thd,hde->the", Ks[n_cal:], W)
            if mode == "stripped":
                # вернуть фазу для честного сравнения в исходных координатах
                pred = apply_rope(pred, cos, sin, pos[n_cal:])
            R2[layer] = r2_per_head(pred, Kt[n_cal:])
        results[mode] = R2
        print(f"== Задание 13.2: R^2 ({mode} RoPE), среднее по головам ==")
        for layer in range(L):
            print(f"  слой {layer}: {R2[layer].mean():.3f}  "
                  f"[{', '.join(f'{v:.2f}' for v in R2[layer])}]")
        print(f"  среднее: {R2.mean():.3f}\n")

    print("Ожидание: stripped заметно выше raw на дальних позициях — "
          "регрессия на RoPE-фазе не переносится по позициям (урок 2608.03893).")


if __name__ == "__main__":
    what = sys.argv[1] if len(sys.argv) > 1 else "all"
    if what in ("all", "sim"):
        sim_ttft()
    if what in ("all", "mapper"):
        run_mapper()

Как проверить

cd modules && python module13.py

Ожидаемый вывод: таблица TTFT для 3 контекстов × 3 битрейтов × 3 каналов, где выигрыш растёт слева направо (fp16 на 25GbE при 64k — самыя слабая точка, int4 на TB4 — самыя сильная); две таблицы R² (raw/stripped) по 6 слоям.

Чеклист:

  • Байт/токен сходится: fp16 = 144 КиБ для Qwen3-8B (2·36·8·128·2), int8 = 72 КиБ, int4 = 36 КиБ.
  • Baseline prefill растёт линейно по контексту: 4k ≈ 0.66 с, 64k ≈ 10.5 с при 100 ТФЛОП/с (расчёт 2·8.2e9·n/1e14).
  • TTFT хэндоффа не зависит от скорости получателя — только от полосы канала и объёма кэша.
  • stripped R² стабильно ≥ raw R² почти на всех слоях; разрыв растёт с длиной калибровочного контекста.
  • Ridge в fit_ridge_per_head устойчив: при lam=1e-2 матрица решается без предупреждений (dx = 32 << T = 384).

Сводка

  • Кэш на Qwen3-8B — 144 КиБ/токен fp16: 25k-контекст весит 3.43 ГиБ, int8 — вдвое меньше; передача этих байт по 23.9 ГБ/с занимает десятки миллисекунд против секунд префилла на слабом узле (расчёт).
  • Решение «где префиллить» — это отношение полосы канала к FLOP-мощности получателя, а не догма: PrfaaS (2604.15039) выносит префилл за пределы RDMA-домена и получает +54% throughput против гомогенного PD на селективном оффлоаде, bandwidth-aware планировании и cache-aware размещении.
  • RDMA перестал быть привилегией датацентров: MCDMA даёт 23.9 ГБ/с и RTT ~8 мкс по четырём Thunderbolt-кабелям, MelonDMA — RDMA на ConnectX из user space macOS (замеры авторов, не независимые).
  • Кэши моделей одного семейства связаны линейно: closed-form ridge-маппер со strip-RoPE даёт 73–98% retention (2608.03893) и работает в 2.7–25× быстрее повторного префилла; strip-RoPE до подгонки обязателен — иначе маппинг не переносится между длинами контекста.
  • CacheBridge (2609.00891) доводит same-family перенос до 99.83% retention через head-матчинг и attention-взвешивание: маппер в 8× компактнее, сборка в 10.7× быстрее.
  • Cross-family SwaT (2610.15095) честен в цифрах: сам по себе 90–110% retention (разброс пар 31–99%), выигрыш +40% accuracy и 4× wall-clock — только в связке с компакцией кэша, против текстового протокола, при обучении <50M токенов и <1 GPU-дня.
  • Перед применением любого метода считайте две арифметики: байты кэша по 2·L·H_kv·d_head·b и секунды префилла получателя по 2Nn/F — они решают всё.


Навигация по курсу: Хаб курса · Предыдущий: Финальный проект: мини-движок инференса · Следующий: Разреженное внимание и длинный контекст