Обновить
32K+
23

LLMOps / AI Platform Engineer

41,1
Рейтинг
18
Подписчики
Отправить сообщение

Померил.

Гонял один и тот же промпт на четырёх глубинах, до настоящего миллиона токенов (1 042 600, это уже под потолок max-model-len). Один поток, ответ 128 токенов, температура 0, пять прогонов на точку. Все цифры сняты со счётчиков движка, а не с клиента, про это ниже отдельно.

Медианы, tok/s:

глубина    с ключом    без ключа
4K           45.9        41.2
64K          45.4        39.0
256K         40.1        32.9
1M           28.0        28.0

Прямой ответ на ваш вопрос: на полном контексте ключ не даёт ничего. По частоте шагов верификации разрыв +9.3% на 4K, +9.8% на 64K, +11.7% на 256K и 0.8% на миллионе. Перепроверил на двух разных типах текста, чтобы не показалось: везде в пределах пары процентов, то есть разницы нет.

Механизм понятный. B12X ускоряет счёт MoE-экспертов, а это фиксированная цена на токен, от длины контекста не зависящая. На коротком контексте она занимает заметную долю шага верификации, отсюда и десять процентов. На миллионе шаг почти целиком уходит во внимание над гигантским KV, доля MoE схлопывается, ускорять становится нечего. Так что флаг имеет смысл для обычной работы и не имеет, если у вас только сверхдлинные контексты.

Заодно ваш вопрос вскрыл в моей методике четыре бага, и все четыре завышали результат.

Самый обидный: клиентские тайминги. Я считал скорость по времени прихода SSE-чанков. На коротком контексте это врёт на процент, а на миллионе сервер начинает паковать несколько шагов верификации в один чанк, и врёт уже на 78%. Один прогон отрапортовал 84 tok/s, то есть быстрее, чем та же машина на 4K. Поймал по физике: 7.94 токена на шаг при потолке 6 (пять черновых плюс свой). Переделал всё на движковые счётчики.

Самый поучительный: филлер. Длинный контекст я строил из одного абзаца, повторённого двести тысяч раз. На такой длине драфтер начинает его щёлкать: приёмка на миллионе подскочила до 56% против ровных 45% на всех остальных глубинах, и миллион показывал 35 tok/s. Сделал несжимаемый текст, приёмка встала на 39%, скорость упала до 28.

И самое интересное, что из этого вышло. Частота шагов на миллионе: 8.54 на повторяющемся тексте и 8.58 на случайном. Одно и то же число. Скорость шага верификации от содержимого не зависит вообще, это чистая цена глубины. А расходятся результаты целиком по приёмке драфтера. То есть с длиной контекста дорожает шаг, а драфтер деградирует не от длины, а от непредсказуемости текста. Два разных механизма, которые обычно меряют одной цифрой.

Про prefill, раз уж речь о полном контексте. Холодный миллион это 1894 секунды, тридцать две минуты до первого токена, 550 tok/s против 1400 на мелкой глубине. Но дописать тысячу токенов в конец уже набранного миллионного диалога стоит около двух секунд, префикс-кэш держит. То есть агент, наращивающий контекст постепенно, не блокируется никогда, а вот «свалить миллион разом и ждать» действительно стоит получаса.

Сырые логи, включая забракованные прогоны и разбор всех четырёх багов, плюс сам гарнесс: github.com/botAGI/dspark-0731-gb10

Тут важный нюанс: 0731 это не просто «дипсик», её как раз переучили под агентов и работу с инструментами. По официальным бенчам DeepSWE прыгнул с 7.3 до 54.4, Terminal Bench с 61.8 до 82.7. То есть ровно то, за что V4-flash ругали, в этом релизе и чинили.

Другое дело, что сам я качество не мерил, у меня в статье только скорость и я это специально оговариваю. Так что если у вас есть замеры по галлюцинациям на MiniMax-M3 против 0731 именно, а не против дефолтной, было бы интересно посмотреть.

Расскажете, что вышло? Интересно, что там с acceptance на вашем tool-бенче))

О, вы реально прогнали, респект. Но там засада: aidendle94 включает B12X сам, у него VLLM_USE_B12X_MOE=1 прямо в образе. Я на нём раньше сидел, переменная до сих пор в моём старом лаунчере валяется. То есть вы сравнили B12X с B12X, понятно, что разницы нет. Моё утверждение вообще про anemll, где auto его молча не берёт.

А вот что у вас реально любопытно, это acceptance 28.5%. У меня на коде 71-73, на русской прозе 36-38. Ваши 28.5 явно ближе к прозе. Мои 67.6 это код, на прозе у меня 43.7.

Про «зачем 20%». У меня не синтетика ради синтетики. Я гоняю агентные сценарии через OpenClaw, по Grafana там 40-45 tok/s. Где-то посередине между моими 67 на коротком коде и 43 на длинной прозе. Когда агент долбит пачками, эти проценты вполне заметны по времени ответа.

Про 2100 МГц, вот это ценно, спасибо. У меня клок не зажат, 3003 максималка.

spec=4 у вас работает, у меня 3 и 7 валидатор отбивал, а в карточке 0731 вообще 7 стоит. Три образа, три разных набора. Про качество apetersson не спорю, я мерил только скорость. 260 это 12 параллельных суммарно, для одного юзера бессмысленно, для агентов норм.

Если захотите ткнуть именно в моё утверждение, это один рестарт: ваш же образ, =0 против =1.

ПС: частоты не лочил, потому что у меня на кластере кастомное охлаждение.

«Ранбук» - это комплимент, спасибо. Именно так и должен выглядеть бенчмарк: протокол, который можно повторить, сырые логи и репозиторий, где меня можно поймать на ошибке. Альтернатива - «я померил, у меня 68», и проверить это никак.

Кстати, в статье я исправляю три собственные ошибки, найденные при перепроверке. Для этого пришлось перемерять. Одну строку в комментариях перемерять не нужно.

Ладно, по порядку)

Триста сниппетов. Триста) На таком объёме эмбеддер вообще не обязателен, там и grep справится. Спорить «толстый или тонкий» на трёхстах документах это как выбирать грузовик под перевозку чайника.

Учить при этом ничего не надо, вы путаете обучение с индексацией. Прогнали свои 300 штук через модель один раз, получили 300 векторов, положили рядом, поиск работает. Дообучение начинается там, где домен уехал далеко и документов на пару порядков больше. Вы всерьёз предлагаете обучать модель ради поиска по трёмстам строкам? Это курсы вождения, чтобы дойти до ларька)

«Это задача толстого эмбеддера!» Вы сейчас с восклицательным знаком процитировали мою же статью) У меня там есть список «когда не стоит брать STRIZH», и в нём отдельной строкой стоит англоязычная нагрузка. Сниппеты кода на английском. EN у меня 0.341 против примерно 0.60 у bge-m3, и я там же сам пишу, что даже mixed 0.624 предъявлять нельзя, потому что набор пересекается с обучением. Обычно с автором спорят, а вы ухитрились согласиться и возразить одной фразой. Читать до конца иногда полезно)

Руль и стабилизация. Если перевести на человеческий, вопрос такой: это вспомогательный компонент внутри большей системы? Да. И это, сюрприз, тоже написано в статье: hybrid retrieval и позиция перед реранкером. Сама по себе модель ничего не решает, я этого нигде и не обещал.

Теперь дебаунс, медленно, потому что тут уже не метафора хромает, а предмет уехал в соседнюю отрасль. Дебаунс это подавление дребезга: контакт скачет, вы фильтруете сигнал во времени и получаете одно нажатие вместо двадцати. Нужны состояние, история и порог срабатывания. У эмбеддера нет ни состояния, ни истории, ни порога, ни времени как такового. Он берёт строку и один раз превращает её в 384 числа. Всегда одинаково, без памяти между вызовами. Подать ему «сигнал сложной формы» некуда, на входе текст, а не осциллограмма. Если вы про то, что запрос у пользователя кривой и его надо причесать, то это другая стадия и другая модель, переписывание запроса. А вопрос «подебаунсит ли эмбеддер кнопку» остался без ответа не потому, что я чего-то не знаю, а потому что это не вопрос. С тем же успехом можно спросить, какой у него радиус поворота)

Жду предметных вопросов или критики по существу, отвечу с числами и ссылками на скрипты, как отвечал выше. За фидбек спасибо, даже за такой)

Перебором подбирались не веса, а то, какие четыре слоя из двенадцати оставить. Веса при этом наследуются от донора дословно: в warmstart_sweep.py обрезка сделана как чистое переименование ключей state_dict, ни градиентов, ни оптимизатора, ни loss там нет вообще. И это дешёвый путь. Наборов я взял четыре (last4, strided, late, spread), прогнал на dev без обучения и оставил лучший старт: late [0,5,9,11] 0.306, last4 [8,9,10,11] 0.281, spread [0,4,8,11] 0.153. Результат strided не сохранился, поэтому в статье его нет. Дорого было бы обучить каждый вариант и потом сравнивать, а так это вечер работы. Аналитически предсказать, какая четвёрка даст лучший старт, я не берусь, и разброс от 0.153 до 0.306 намекает, что гадание тут вышло бы боком.

По терминам - STRIZH не LLM!!! Это энкодер-ретривер: один forward-проход, mean pooling, на выходе вектор длины 384. Он ничего не генерирует, поэтому никакой «степени исполнительности» у него нет.

Поэтому и вопрос про сложный инференс между группами слоёв отпадает сам. У четырёхслойного энкодера таких групп физически нет, схема и так минимальная, оптимизировать в ней нечего))))) Ограничение ggml, о котором вы пишете, здесь ничего не связывает.

Типы слоёв, кстати, не подбирают у соседних моделей, их наследуют от донора. Откройте config.json опубликованной модели: layer_types: ['full_attention', 'sliding_attention', 'full_attention', 'sliding_attention'], и rope theta у типов разная, 160000 против 10000. При обрезке эти поля обязаны переехать вместе со слоями, иначе получите rope mismatch, и модель деградирует молча, без единой ошибки в логах. Об этом написано первой строкой в докстринге warmstart_sweep.py.

Насчёт подготовки выборки да! у меня это в выводах отдельным пунктом: hard negatives дали +0,9 п.п. (0.737 → 0.746) там, где рост корпуса в 2,44 раза дал +0,3. Сложность сигнала решает))

Четыре слоя, не 11: [0, 5, 9, 11] - индексы из 12 донорских. Набор выбран перебором, цифры и скрипт в статье. Выборку не публиковал, о чём там же написано!! опубликован конвейер, повторяйте на своём корпусе.

Для одной 27B в Q4 хватило бы и 64. 128 работают на другое: в контеншен-тесте статьи одновременно жили генерация, эмбеддинги и реранкер, и GPU-маппинги занимали за 50 ГиБ вместе с KV-кэшами на 32 слота. Плюс два инстанса по 20 ГБ для топологических экспериментов, плюс запас под модели 70B+ класса, которые сюда влезают, но упрутся уже в полосу памяти, а не в объём. То есть 128 это не «одна модель побольше», а «стек целиком на одной коробке».

Так статья ровно это и говорит. 32 слота по 8К это режим коротких запросов: чат, агентные вызовы, батч-задачи. Для длинных промптов есть отдельный раздел с честными числами: уже на 3,4К токенов узел упирается в обработку промптов, и комфортная зона заканчивается на четырёх клиентах, а не тридцати двух. Никто не предлагает возить 32 RAG-сессии на одной коробке, замер показывает ровно обратное.

Справедливо. Внутримодельные сравнения статьи (долина, кванты, топология, MTP) от этого не зависят, там токенайзер один и тот же. А вот кросс-модельное 236 против 178 это токены родных токенайзеров, и в символах на русском разрыв может быть другим. Символы/с я не логировал, добавлю как ограничение в репозиторий. Спасибо.

Согласен, к wavefront восьмёрка не мапится, я и не привязывал долину к железу. Моя рабочая гипотеза программная: где-то в цепочке llama-server и Vulkan-бэкенда есть порог на размер decode-батча, за которым меняется путь исполнения (класс ядер или разбиение батча), и 8 одновременных генераций сидят по одну его сторону, а 10 по другую. В пользу софтового порога говорит и то, что обрыв идентичен у двух разных архитектур и трёх квантов, и то, что он не сдвинулся ни от смены ядра Linux, ни от типа KV, ни от батч-флагов. Ваша версия про KV-слоты тоже живая. Профилированием я это не добивал, в репо есть всё для воспроизведения, если захотите копнуть: обрыв ловится за один 75-секундный прогон.

Спасибо. История с реранкером ещё и самая дешёвая из всех: один запрос к /props вместо ребут-эксперимента, который я уже собирался делать. С тех пор сверяю эффективный конфиг, а не командную строку, везде.

Замерил на 7.0.0-28. Генерация: Qwen на 8 клиентах 149 → 155, на 32 клиентах 160 → 159; Gemma на 32 клиентах 236 → 243. Embed 192 → 199 rps, rerank 7,0 → 7,3. Итого дельта ядра в пределах пары процентов, в рамках межпрогонного разброса, а провал на переходе через 8 одновременных запросов на новом ядре воспроизводится один в один. Сырые прогоны добавил в репо.

Beelink просит $4,349 по pre-sale при зачёркнутых $4,699, я их в спойлере со сравнением приводил. На старте GTR9 Pro стоил около двух тысяч, всё что сверху это дефицит LPDDR5X 2026 года, он же задрал Spark с $3,999 до $4,699. Ну и свет клином на Beelink не сошёлся, Strix Halo со 128 ГБ есть у GMKtec, Framework и других, местами заметно дешевле.

Про замену маку да, похоже. Только у мака Docker крутится в виртуалке, а тут нативный Linux. Когда на узле 34 контейнера, это чувствуется. Я эту коробку вообще брал не под инференс, инференс тут бонусом.

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

Отвечу на вопрос «зачем» прямо. Это не домашняя ML-лаба и не публичный многопользовательский сервис. Это собственная приватная инфраструктура: документы и данные не покидают контур, поэтому сервисный стек работает на нашем железе. Узлы из статьи закрывают в нём конкретную роль: сервисному слою нужны обычная amd64-экосистема и большой пул памяти, а не максимальные TFLOPS.

Теперь разделю два узла и два разных теста, которые вы снова объединили. Опубликованные p50/p95 относятся к embed и rerank на Strix-A. Embed-сервис запущен с --parallel 4. Эти перцентили сняты на 50 последовательных измерениях. Отдельно был 90-секундный ресурсный тест с четырьмя потоками embed и двумя потоками rerank. Он проверял загрузку GPU и запас по лимитам, а не конкурентный p95.

--parallel 1 использовался только в контекстном тесте Qwen на Strix-B. Никаких p95 и multi-user SLO для Qwen я не заявлял. Более того, параллельная генерация прямо находится в разделе «Не проверено».

Именно поэтому рабочая пользовательская очередь находится не на Strix-B, а на паре DGX Spark с vLLM, continuous batching и paged attention. Strix-B это отдельный автономный узел и ручной резерв, а не замена основного генерационного тира. Для разных нагрузок в одной топологии используются разные инструменты, а не одна универсальная коробка.

Постоянный инфраструктурный узел в статье это прежде всего Strix-A: 34 контейнера, месяц эксплуатации при небольшом трафике, перезагрузка хоста, перезапуск Docker с live-restore, ресурсные измерения и отдельный конкурентный тест embed/rerank. Это field report по конкретной эксплуатации, а не сертификация под произвольное количество пользователей. Обратного в статье не заявлено.

Для нашего сценария показатели embed/rerank уже отвечают на вопрос о применимости: p95 эмбеддинга батча из 32 текстов составил 184 мс, то есть около 174 текстов в секунду; p95 реранка двадцати кандидатов составил 142 мс. Между p50 и p95 во всех трёх тестах не более 2 мс. В текущем RAG-контуре эти 142 мс не являются доминирующей задержкой на фоне генерации. Конкурентный профиль и p99 я не измерял и прямо это указал.

Одна или две RTX A6000 действительно могут быть лучшим выбором для CUDA, vLLM и высокой конкурентности. Статья не утверждает обратного. В моей конфигурации запуск Qwen увеличил занятый GTT примерно на 27,7 ГиБ, поэтому на одной A6000 с 48 ГБ аналогичная конфигурация потенциально могла бы поместиться без CPU offload. Тогда сравнивать нужно фактические throughput, latency, concurrency, энергопотребление и стоимость всей системы.

Если же использовать CPU offload, это уже не вариант «без танцев»: сама документация vLLM предупреждает, что выгруженные параметры подаются из CPU memory во время forward pass и требуют быстрого CPU-GPU интерконнекта. Но без прямого теста двух стендов я не буду назначать победителя по теоретическим цифрам.

И нет, эти коробки никому не «впариваются». В статье описан наш внутренний приватный контур. Коммерческий сценарий вы добавили самостоятельно, а затем предъявили его мне как тезис статьи.

Если вы видите конкретную фактическую ошибку в конкретном абзаце, процитируйте её. На предмет статьи, роли узлов и границы проведённых тестов я ответил. Спасибо за дискуссию.

Спасибо за подробный разбор. Начну с того, что вынесло меня сильнее всего: вопрос про дообучение. Слово «обучение» в ней не встречается ни разу. Вы спорите со статьёй «домашняя лаба ML‑инженера», которая у вас в голове, а моя про другое: выдержит ли эта коробка роль постоянного инфраструктурного узла. Соберусь тюнить LoRA на 8060S, напишу отдельный текст, и вот там ваш скепсис будет по адресу.

То же самое с vLLM, paged attention и continuous batching. Вы требуете ровно то, что в системе уже есть, и ровно там, где ему место. Прод‑генерацию стек получает по LAN с пары DGX Spark. Там крутится vLLM со всем перечисленным, и как эта пара держит multi‑user, я разбирал в отдельной статье, ссылка есть в тексте. Strix‑B в этой топологии автономный резерв. Претензия «на резервном узле нет continuous batching» звучит примерно как «в запаске нет датчика давления».

Теперь по вашим номерам.

  1. --parallel 1 это параметр запуска моего же бенчмарка, опубликованный в разделе «Методика». То есть вы цитируете мне мою методику в жанре разоблачения. Слоты задаются флагом сервера, это не свойство железа. Поменять цифру стоит одну строку, а поведение под параллельными потоками честно лежит в «Не проверено». И повторюсь: очередь пользователей стоит не сюда, а на Spark.

  2. Тут прочитано зеркально. Главный результат аудита: у всех 40 внешних пинов есть готовые linux/amd64-манифесты, собирать не пришлось ничего. Локально собираются три образа, и это наши собственные агентские сервисы. Их не существует ни под какую архитектуру, пока мы их не соберём, так что их пришлось бы собирать и на «нормальном железе».

  3. Тут согласны.

4.Про sandbox перепутаны две разные величины: 95% это доля от лимита в 1 ГиБ, который контейнеру выставил я сам, а на хосте в этот момент свободно 98,8 ГиБ. Впритык у нас не память, а моя осторожность в дескрипторе, и статья ровно это говорит: сигнал проверить лимит под code‑execution‑нагрузкой, а не симптом дефицита.

Про пригодность эмбеддингов и реранка ответ не «неизвестно», ответ в опубликованных цифрах. Реранк двадцати кандидатов занимает 141 мс, эмбеддинг батча из 32 текстов 182 мс, это порядка 175 текстов в секунду на индексации. На 50 повторах между медианой и p95 не больше двух миллисекунд, хвост на последовательных запросах практически отсутствует. В пайплайне, где после реранка идёт генерация на секунды, эти 141 мс погоды не делают. Статья и заявляет пригодность именно для описанного в ней сценария с небольшой параллельностью, а не для абстрактного хайлоада. Конкурентный профиль и p99 лежат в «Не проверено», и здесь мы совпали, потому что оба цитируем один и тот же абзац. Когда обе стороны спора ссылаются на один абзац, это уже не спор, а совместное чтение.

  1. Вы пересказали раздел статьи в качестве возражения к нему. Эти счётчики и должны показывать разное: docker stats вычитает inactive_file, memcg GTT‑страницы практически не учитывает. Поэтому вывод в тексте совпадает с вашим: планировать по mem_info_gtt_used, он один и детерминированный. И деталь, которая закрывает сценарий «при 256K и нескольких сессиях памяти не хватит»: KV‑буфер под всё окно 256K выделяется при старте сервера. Это те самые 2,7 ГиБ, у Qwen3.6 гибридная архитектура и классических attention‑слоёв всего десять. Потолок памяти известен до первого токена, внезапности в этой конструкции физически негде взяться.

Про космический эффект: космического не обещал. Обещанный эффект скучнее: 34 контейнера, месяц работы стека, пережитые перезагрузка хоста и рестарт демона Docker, ноль ARM‑сборок. Буханка? Согласен, буханка. Она тем и хороша, что едет каждый день, пока нормальное железо согласовывает бюджет.

Спасибо, что прочитали внимательно. Местами внимательнее, чем написано.

буду прыгать от радости если предложат оффер поработать с таким железом)

Здравствуйте! как раз под эту проблему надеюсь на след неделе выпущу статью) конкретного решения еще нет к сожалению..

Спасибо, что обращаете внимание на эту тему — про неё почему-то мало говорят, все радуются облакам и не думают, куда уходят их данные. Сам ни разу не пожалел, что выбрал вектор локальных нейросетей: всё крутится на своём железе, и спится спокойнее)

1

Информация

В рейтинге
191-й
Зарегистрирован
Активность

Специализация

ML
От 333 333 $
Linux
Git
Docker