Экспериментальный O(1)-режим CMF заменяет растущий KV-кэш в 16 full-attention слоях Qwen3.8-27B фиксированным состоянием 44,1 МиБ. На длине 64K это сопоставляется с 4 ГиБ FP16 KV-кэша, но ценой приближённого восстановления дальнего контекста.

Статья про CMF формат

В CMF можно включить экспериментальный режим O(1). Он заменяет KV-кэш в полных attention-слоях компактным состоянием фиксированного размера: недавние токены сохраняются точно, начало последовательности — в постоянном наборе sink-токенов, а дальняя часть представляется набором опорных представлений. Это позволяет запускать конвертированную Qwen3.8-27B Q4TP на карте класса от 16 ГБ и не увеличивать размер этой части состояния вместе с длиной контекста.

Цена известна заранее: текущая модель обучалась для обычного внимания, поэтому перенос является приближением. Дальние факты могут восстанавливаться хуже, а первый токен длинного запроса получается медленнее. O(1) здесь означает постоянный размер состояния при фиксированных параметрах; время обработки самого входа всё равно зависит от числа токенов.

Что именно запускаем

Qwen3.8-27B — гибридная модель из 64 слоёв: 48 слоёв Gated DeltaNet с уже рекуррентным состоянием и 16 слоёв полного attention. CMF-файл qwen38-27b-q4tp.cmf содержит 4-битные веса в формате Q4TP. Его размер — 14 271 151 208 байт, то есть около 14,3 GB в десятичной записи.

Готовый файл опубликован в репозитории модели на Hugging Face.

Флаг --o1 можно передать при запуске уже готового файла. Конвертация с cortiq convert --o1 тоже поддерживается, но записывает только подсказку в заголовок: веса остаются неизменными, а режим выбирается рантаймом. Поэтому для этой демонстрации не требуется заново конвертировать чекпойнт и не требуется дообучение.

Идея на бытовом уровне

Представьте магазин с тысячами покупок. Можно записывать каждую покупку отдельной строкой — тогда журнал постоянно растёт. А можно одновременно обновлять сводную таблицу: количество продаж, выручку, число заказов. Каждая покупка влияет на показатели, но количество ячеек в таблице остаётся прежним. В CMF используется похожий принцип накопления. Недавний текст сохраняется подробно, а более ранний контекст участвует в обновлении компактного числового состояния. При ответе модель использует обе части: свежие подробности и накопленную информацию о предыдущем разговоре. Новый текст обновляет уже выделенную память, поэтому для каждого следующего фрагмента не требуется увеличивать хранилище всей истории. Именно это даёт постоянный объём состояния O(1). Пример с магазином объясняет принцип; вычисления внимания в CMF значительно сложнее обычных сумм и счётчиков.

Сколько памяти занимает контекст

Ниже сравнивается именно память состояния полного attention, без весов и остальных буферов. Для Ollama взят документированный FP16 KV-кэш по умолчанию; квантизация весов Q4 сама по себе не делает KV-кэш 4-битным. Источник настройки KV-кэша — документация Ollama.

Длина контекста

Ollama: FP16 KV-кэш

CMF O(1): состояние attention

Отношение

2 048

128 МиБ

44,1 МиБ

2,9×

4 096

256 МиБ

44,1 МиБ

5,8×

8 192

512 МиБ

44,1 МиБ

11,6×

16 384

1 ГиБ

44,1 МиБ

23,2×

32 768

2 ГиБ

44,1 МиБ

46,4×

65 536

4 ГиБ*

44,1 МиБ*

92,9×

131 072

8 ГиБ*

44,1 МиБ*

185,8×

262 144

16 ГиБ*

44,1 МиБ*

371,6×

1 МиБ = 2^20 байт, 1 ГиБ = 2^30 байт. Длина — общее число удерживаемых токенов, включая вход и уже сгенерированный ответ. Столбец O(1) — фактический счётчик 46 236 672 байта (44,0947 МиБ) для m=32, окна 128, четырёх sink-токенов и калибровочного префикса 256 токенов. Это одна GPU-копия состояния внимания, а не размер всей модели.

Расчёт растущей части для Qwen3.8-27B выглядит так:

16 полных слоёв × 4 KV-головы × 256 × 2 (K и V) × 2 байта = 65 536 байт на токен

48 слоёв GDN уже используют собственное рекуррентное состояние и не входят в растущую часть таблицы. Кроме него остаются веса, рабочие буферы, драйверные выделения, хостовая копия состояния и временная память префилла. Поэтому 44,1 МиБ нельзя читать как «вся модель занимает 44 МиБ».

Если точный обычный KV хранить в f32, его payload будет вдвое больше: 131 072 байта на токен. В таблице намеренно показан FP16-вариант Ollama, чтобы сравнение соответствовало документированному значению по умолчанию.

Строки O(1) для 8k–32k совпадают с завершёнными измерениями. Строки со звёздочкой — экстраполяция постоянного состояния и формульный расчёт KV-кэша, а не подтверждение запуска модели на 256k и не гарантия качества на такой длине. Ollama в этой таблице также не прогонялся на каждой длине.

Если после загрузки весов и прочих буферов на карте осталось 4 ГиБ, один только FP16 KV-кэш этой модели израсходует такой бюджет примерно на 64k токенов. O(1) снимает линейный рост именно этого компонента; пределы модели, время обработки входа и качество сжатой памяти остаются.

Установка на Linux с Vulkan

Ниже приведён рецепт для NVIDIA Vulkan. На проверенном стенде это RTX PRO 4000 Blackwell с 24 467 МиБ доступной VRAM и лимитом мощности 145 Вт. Для хост-системы стоит иметь 64 ГБ оперативной памяти и запас на диске под файл модели, временные данные и сборку. Универсальный минимальный объём для всех карт здесь не объявляется: он зависит от драйвера, рабочих буферов и выбранного файла.

До установки пользовательских Vulkan-пакетов установите совместимый драйвер NVIDIA официальным способом для своего дистрибутива. libvulkan1, libglvnd0 и vulkan-tools — это загрузчик и инструменты; они сами по себе не устанавливают ядровой драйвер. Быстрая проверка — nvidia-smi, затем vulkaninfo --summary.

Вариант 1: готовый бинарник релиза

Имена архивов соответствуют workflow сборки релизов. Для Linux x86_64 используется cortiq-x86_64-unknown-linux-gnu.tar.gz:

mkdir -p cmf-qwen38
cd cmf-qwen38

curl -LO https://github.com/infosave2007/cmf/releases/download/v0.6.6/cortiq-x86_64-unknown-linux-gnu.tar.gz
curl -LO https://github.com/infosave2007/cmf/releases/download/v0.6.6/cortiq-x86_64-unknown-linux-gnu.tar.gz.sha256
sha256sum -c cortiq-x86_64-unknown-linux-gnu.tar.gz.sha256

tar -xzf cortiq-x86_64-unknown-linux-gnu.tar.gz
mkdir -p "$HOME/.local/bin"
install -m 0755 cortiq "$HOME/.local/bin/cortiq"
export PATH="$HOME/.local/bin:$PATH"
cortiq --version

Ожидаемый вывод последней команды для этого материала — cortiq 0.6.6. Ссылки на архивы и статус сборки находятся на странице релиза v0.6.6.

Вариант 2: установка через Cargo

Используйте актуальный stable toolchain. Указанный в проекте rust-version = 1.85 — нижняя граница манифеста, а требования зафиксированных транзитивных зависимостей могут потребовать более свежий stable:

rustup toolchain install stable
cargo +stable install cortiq-cli --version 0.6.6 --locked
cortiq --version

Обычная установка cortiq-cli включает GPU-функции. CPU-only вариант собирается отдельно с --no-default-features; для описанного Vulkan-профиля этот вариант не нужен.

Загрузить и проверить модель

Установите CLI Hugging Face (hf) по официальной инструкции. Компактный изолированный вариант через Python выглядит так:

python3 -m venv .venv
. .venv/bin/activate
python -m pip install --upgrade huggingface_hub
hf --help

После этого скачайте ровно один файл из закреплённой ревизии:

hf download infosave/Qwen3.8-27B-cmf qwen38-27b-q4tp.cmf \
  --revision 31699079edefe40c9d1223158597fbfa37c234ce \
  --local-dir .

printf '%s  %s\n' \
  'eec6a35934f45e16cfcff3c0c223846aa498cb8fb419e675e3b73b708c00655c' \
  qwen38-27b-q4tp.cmf | sha256sum -c -

cortiq verify qwen38-27b-q4tp.cmf
cortiq info qwen38-27b-q4tp.cmf

Проверка SHA-256 защищает от неполной загрузки или подмены файла. cortiq verify открывает CMF-контейнер, проверяет envelope, границы секций, каталог тензоров и хэши каждого тензора; при наличии файла .sig дополнительно проверяется detached Ed25519-подпись, а отсутствие sidecar не считается ошибкой. Это отдельные проверки целостности файла и подписи. Команда info читает контейнер и печатает архитектуру, слои, головы и квантование; инференс она не запускает.

Настроить GPU и запустить O(1)

Сначала проверьте, какой адаптер видит Vulkan:

sudo apt update
sudo apt install libvulkan1 libglvnd0 libegl1 libgl1 libglx0 vulkan-tools

export XDG_RUNTIME_DIR=/tmp
cortiq gpu

cortiq gpu перечисляет адаптеры, выбранное устройство и его лимиты; при наличии адаптера дополнительно измеряет пустой roundtrip до устройства. Модель он не загружает и не запускает. Если в списке несколько карт, выберите номер из вывода cortiq gpu. Вместо номера можно использовать подстроку имени, например CMF_GPU_ADAPTER=5090.

Для воспроизводимого запуска Qwen3.8-27B на Vulkan используется следующий профиль. Это набор параметров конкретного измеренного стенда, а не обязательный набор для каждой видеокарты:

export CMF_GPU=1
export WGPU_BACKEND=vulkan
export XDG_RUNTIME_DIR=/tmp
export CMF_GPU_ADAPTER=0
export CMF_GPU_PROBE=0

export CMF_BATCH_K=128
export CMF_BATCH_COOP=1
export CMF_GRAPH_BGCACHE=0
export CMF_GRAPH_SPLIT=16
export CMF_PASSFUSE=1
export CMF_GPU_GROUP=1

export CMF_GRAPH_SPEC=0
export CMF_MTP=0
export CMF_VERIFY_I8=0
export CMF_O1_GPU=1
export CMF_O1_PREFILL=256
export CMF_KV=f32

Что означают существенные настройки:

Настройка

Значение в профиле

Назначение и базовое поведение

CMF_GPU

1

запросить GPU; без переменной используется CPU-путь

WGPU_BACKEND

vulkan

выбрать Vulkan для wgpu

CMF_GPU_ADAPTER

0

адаптер по индексу; значение по умолчанию — 0

CMF_GPU_PROBE

0

доверять GPU без стартового чередования CPU/GPU; по умолчанию проба включена

CMF_BATCH_K

128

батч префилла; по умолчанию 0, то есть последовательный путь

CMF_BATCH_COOP

1

включить cooperative-matrix путь широкого батча; по умолчанию выключен

CMF_GRAPH_SPLIT

16

число частей графа; в текущем рантайме значение по умолчанию 16

CMF_GPU_GROUP

1

объединять независимые проекции в один pass; по умолчанию включено

CMF_PASSFUSE

1

сливать соседние последовательные этапы графа; по умолчанию включено

CMF_GRAPH_SPEC / CMF_MTP

0

выключить speculative decode для сопоставления с O(1); без явного 0 MTP может включаться для подходящего greedy-пути

CMF_VERIFY_I8

0

выбрать f32-проверку speculative-пути; по умолчанию используется int8, но в этом профиле speculative decode выключен

CMF_O1_GPU

1

выполнять O(1) attention на GPU; GPU-ветка O(1) opt-in

CMF_O1_PREFILL

256

точный калибровочный префикс перед запечатыванием; без переменной префикс следует обычной полной обработке запроса

CMF_KV

f32

точный KV-тип для этого O(1)-пути; по умолчанию также f32

CMF_GRAPH_BGCACHE=0 в профиле оставляет кэш bind-group выключенным, чтобы результат совпадал с принятой серией. CMF_GRAPH_SPLIT, CMF_GPU_GROUP и CMF_PASSFUSE влияют на граф и могут дать другое время на другой карте. Если вы меняете их, заново измерьте свой стенд.

После загрузки состояния запустите одношаговый ответ:

cortiq run qwen38-27b-q4tp.cmf \
  --o1 all --o1-m 32 --o1-window 128 --o1-sink 4 \
  --temperature 0 --seed 42 --rep-penalty 1.0 \
  --no-think --max-tokens 256 \
  --prompt 'Объясни простыми словами, зачем языковой модели фиксированная память контекста.'

--o1 all означает «перевести доступные полные attention-слои», то есть в этой гибридной модели 16 слоёв. 48 GDN-слоёв продолжают использовать свой рекуррентный механизм. --o1-m 32 задаёт число landmarks, --o1-window 128 — размер точного окна, --o1-sink 4 — число точных ключей в начале последовательности.

--no-think просит шаблон чата сразу вывести ответ без блока рассуждений. Он несовместим с --raw: последний подаёт строку модели без chat template. Если нужен raw-режим, уберите --no-think и добавьте --raw отдельным запуском. --temperature 0, --seed 42 и --rep-penalty 1.0 фиксируют воспроизводимый greedy-профиль без штрафа повторов.

После ответа run печатает количество токенов, время до первого токена, скорость последующего декода, общую скорость и причину завершения. Это позволяет отделить медленный префилл от steady-state decode, не измеряя вывод терминала вручную.

Для обычного режима на том же файле используйте явное отключение O(1):

CMF_O1_GPU=0 cortiq run qwen38-27b-q4tp.cmf \
  --o1 off \
  --temperature 0 --seed 42 --rep-penalty 1.0 \
  --no-think --max-tokens 256 \
  --prompt 'Объясни простыми словами, зачем языковой модели фиксированная память контекста.'

Для честного A/B сравнения оставьте одинаковыми файл, промпт, число выходных токенов, seed и backend. O(1) и speculative decode в текущем runtime используют разные жизненные циклы состояния, поэтому измеренный профиль выше намеренно задаёт CMF_MTP=0.

Серверный режим

Одноразовый run --prompt завершает процесс после ответа. Если приложение само передаёт историю диалога, можно поднять локальный HTTP-сервер и отправлять её в OpenAI-совместимый endpoint:

cortiq serve qwen38-27b-q4tp.cmf \
  --host 127.0.0.1 --port 8080 \
  --o1 all --o1-m 32 --o1-window 128 --o1-sink 4

Доступны /v1/models, /v1/chat/completions и /v1/completions. /v1/models возвращает один рекламируемый идентификатор вида <arch>-cortiq; поле model в запросе обязательно и возвращается в ответе, а файл выбирается позиционным аргументом serve. Пример запроса к чату:

curl http://127.0.0.1:8080/v1/chat/completions \
  -H 'Content-Type: application/json' \
  -d '{"model":"Qwen3.8-27B-cmf","messages":[{"role":"user","content":"Что такое O(1) память?"}],"temperature":0,"max_tokens":256,"enable_thinking":false}'

enable_thinking:false передаётся в chat template и подавляет <think>; верхнеуровневое поле имеет приоритет над chat_template_kwargs.enable_thinking. Для файла с task masks можно добавить "cortiq":{"task":"имя-маски"}: неизвестная маска вернёт 404, без поля используется выбор сервера из --task (по умолчанию general). Историю нужно передавать в messages на каждом запросе, как и в обычном OpenAI-совместимом клиенте. CMF не загружается в Ollama автоматически: для .cmf используйте cortiq, а Ollama оставьте отдельным baseline с его собственной моделью.

Как устроен переход на O(1)

При обычном префилле рантайм строит точное состояние для начальной части запроса. Переменная CMF_O1_PREFILL=256 ограничивает калибровочный префикс: эти токены проходят точное внимание, по их запросам строится скелет, затем полные временные K/V для O(1)-слоёв освобождаются. Остаток длинного промпта и последующая генерация идут через потоковый оператор.

Слово «переход» важно: на длинном запросе первый токен не становится мгновенным. Точная подготовка префикса и построение опорных представлений занимают время, зато после запечатывания размер состояния не растёт от каждого следующего токена. При коротком запросе, который помещается в sink + window с небольшим запасом, скелет может вообще не включаться — это нормальный точный путь.

Внутри O(1) есть три части:

  1. постоянные sink-ключи для первых четырёх позиций;

  2. кольцо последних 128 ключей и значений, которые читаются точно;

  3. опорные представления и накопители дальней части, ограниченные бюджетом m=32.

Параметры по умолчанию для этого runtime — m=32, window=128, sink=4. Для wgpu-пути проверка геометрии допускает 4 ≤ m ≤ 32, sink + window ≤ 2052 и размерность головы до 256; у Qwen3.8-27B это head_dim=256. При неподдерживаемой геометрии O(1)-граф не выполняется; для превышения runtime cap в журнале появляется o1 geometry over kernel limits, поэтому широкое окно нельзя считать запущенным на GPU без проверки журнала. Окно 2048 вместе с четырьмя sink-токенами помещается в геометрический предел, но остаётся экспериментальным; валидированный скоростной профиль статьи использует 128.

Воспроизвести измерение скорости командой bench

bench сам строит синтетический вход указанной длины. Флаг --core исключает рабочую копию, штраф повторов и per-token confidence, чтобы измерять базовый цикл в стиле llama-bench. --ignore-eos не даёт короткому EOS завершить замер, а --json печатает машиночитаемый объект.

После применения профиля выше команда O(1) имеет такой синтаксис:

cortiq bench qwen38-27b-q4tp.cmf \
  --ctx 8192 --tokens 128 --ignore-eos --core \
  --o1 all --o1-m 32 --o1-window 128 --o1-sink 4 --json

Контрольный запуск на том же файле:

CMF_O1_GPU=0 CMF_MTP=0 cortiq bench qwen38-27b-q4tp.cmf \
  --ctx 8192 --tokens 128 --ignore-eos --core \
  --o1 off --json

--ctx 8192 задаёт длину синтетического входа, а --tokens 128 — число генерируемых токенов. В отличие от готового ответа, benchmark не доказывает качество дальнего извлечения фактов: он показывает время и счётчики выбранного пути.

Что измерено на 24-ГБ карте

Итоговая серия состояла из шести чередующихся запусков: три контрольных и три с новым GPU-readout ядром. В каждом было 8192 входных и 128 выходных токенов, Vulkan, Q4TP, пакет 128, COOP1, O(1) с m=32, окном 128, четырьмя sink-токенами и префиксом 256; MTP был выключен.

Показатель

Контроль

Новое ядро

Изменение

TTFT, медиана

73,821774 с

68,311079 с

−7,46%

Скорость обработки входа, через TTFT

110,970 ток/с

119,922 ток/с

+8,07%

Последующая генерация

25,771462 ток/с

26,172550 ток/с

+1,56%

Состояние O(1) на GPU

46 236 672 байта

46 236 672 байта

без роста

В новом GPU-readout ядре 32 независимых столбца сжатого состояния читаются разными потоками GPU. Порядок суммирования внутри каждого столбца и формула Aggregate сохранены, поэтому это ускорение чтения, а не новая схема аппроксимации. Все шесть запусков прошли с 16 O(1)-слоями и без пропусков графа.

Стенд: RTX PRO 4000 Blackwell, 24 467 МиБ VRAM, Xeon E5-2690 v4, 64 ГБ RAM. Это сравнение двух сборок одного проекта на одной карте, а не универсальный результат для всех GPU. Из серии не получался новый непрерывный замер пика всей VRAM; число 44,1 МиБ относится только к GPU-состоянию O(1). Эти данные также не являются парным сравнением скорости CMF с Ollama: у них были разные условия и квантизации.

Где текущий подход приближённый

Текущий O(1) — эмуляция внимания уже обученной модели. Модель не училась кодировать каждый дальний факт в 32 опорных представлениях, поэтому компактное состояние может терять детали, особенно за пределами точного окна. Оператор не эквивалентен полному softmax attention, а вывод не обязан совпадать с --o1 off токен в токен.

Есть и инженерные границы:

  • O(1) ограничивает размер состояния внимания, но не стоимость чтения всего входа. Префилл длинного запроса всё равно требует времени, а калибровочный префикс временно использует точное состояние на CPU.

  • В таблице не учтены 14,3 GB весов Q4TP, 48 GDN-состояний, scratch, драйвер и хостовые копии. Реальный бюджет карты всегда больше, чем сумма одной ячейки таблицы.

  • Номинальное окно Qwen в 262 144 токена не означает, что O(1) доказал качество или успешный запуск на такой длине. Для строк выше 32k приведена только геометрическая экстраполяция памяти.

  • m=32, окно 128 и sink 4 — принятый профиль. Большое окно 2048 экспериментально и не является рекомендацией по качеству.

  • Обычный Ollama может включить Q8 или Q4 KV-кэш; это уменьшает линейный коэффициент примерно в два или четыре раза, но не меняет O(N) рост. Применимость зависит от модели и backend.

Диагностика

Не найден Vulkan-адаптер. Проверьте cortiq gpu, установку loader-пакетов и vulkaninfo --summary. На headless Linux задайте XDG_RUNTIME_DIR=/tmp. Если нужна CPU-проверка, запускайте отдельную команду с CMF_GPU=0; не приписывайте её скорость GPU.

Недостаточно VRAM. Убедитесь, что файл именно Q4TP и его SHA-256 совпадает. Проверьте, не занята ли выбранная карта другой вашей задачей, и выберите нужный адаптер через CMF_GPU_ADAPTER. Для долгого запроса оставьте запас под GDN и рабочие буферы; переход на CPU — честный контрольный вариант, а не доказательство ускорения.

Первый токен слишком медленный. Для длинного входа это ожидаемая цена CMF_O1_PREFILL=256: рантайм собирает точный префикс и запечатывает landmarks. Смотрите последующую скорость декода отдельно. Для диагностики используйте RUST_LOG=info и проверьте, что нет сообщения o1 geometry over kernel limits.

O(1) не включился на GPU. Оставьте CMF_O1_GPU=1 и CMF_KV=f32, передайте явный --o1 all, а затем проверьте журнал. Q8 KV-кэш полезен для обычного режима, но этот O(1)-профиль проверен с F32 KV. При --o1 off вы намеренно сравниваете полный attention.

Ответ хуже на дальнем факте. Повторите тот же prompt с --o1 off. Если нужна точность старого контекста, уменьшите область применения O(1) через --o1 deepN или список слоёв либо оставьте обычный режим. Увеличение окна меняет скорость и память рабочего пути и пока не имеет здесь отдельного quality gate.

Результат не воспроизводится. Закрепите ревизию HF, проверьте SHA-256, используйте одинаковый seed, backend, env-профиль и длину входа. Для скорости прогревайте GPU отдельно и сравнивайте медианы повторов; один холодный запуск смешивает загрузку весов и компиляцию шейдеров с самим декодом.

Куда развивается нативный вариант

Конвертация без обучения полезна как способ проверить формат, память и runtime на уже существующих моделях. Следующий естественный шаг — обучать или адаптировать модель с тем же механизмом фиксированной памяти, который будет использоваться при инференсе. Тогда модель сможет заранее учиться записывать и извлекать полезную информацию из ограниченного состояния, а исполнитель — использовать операции, рассчитанные на эту схему. Цель направления — одновременно улучшить точность сжатой дальней памяти и ускорить исполнение; размер будущего выигрыша должен быть подтверждён отдельными сопоставимыми измерениями.

Параллельно проект развивает быстрый нативный формат исполнения без роста KV-кэша и адаптацию моделей под тот же механизм. Цель направления — улучшить качество дальней памяти и скорость; для нативной 27B-модели нужны отдельные сопоставимые измерения.

В публичном реестре проекта указана патентная заявка США № 19/738,763 от 13 июля 2026 года, относящаяся к конвертации потокового внимания с постоянной памятью без обучения. Исходная запись находится в PATENTS.md.

Итоговая шпаргалка

# файл модели уже скачан и проверен
export CMF_GPU=1 WGPU_BACKEND=vulkan XDG_RUNTIME_DIR=/tmp
export CMF_GPU_ADAPTER=0 CMF_GPU_PROBE=0 CMF_KV=f32
export CMF_O1_GPU=1 CMF_O1_PREFILL=256 CMF_MTP=0 CMF_GRAPH_SPEC=0

cortiq run qwen38-27b-q4tp.cmf \
  --o1 all --o1-m 32 --o1-window 128 --o1-sink 4 \
  --temperature 0 --seed 42 --rep-penalty 1.0 \
  --no-think --max-tokens 256 --prompt 'Ваш запрос'

Начните с этих параметров, сравните несколько своих запросов с --o1 off, а затем решайте, подходит ли компромисс дальнего контекста вашему сценарию. В этом и состоит практическая ценность режима: фиксированное состояние внимания становится измеряемым ресурсом, а потеря точности — явным параметром эксперимента.

Источники: модель Qwen3.8-27B на Hugging Face, исходный репозиторий CMF, релиз v0.6.6, официальная документация Ollama о KV-кэше.