Перейти к содержанию
Публикация AiManual

PR #31028 в llama.cpp: что меняется при конвертации Qwen в GGUF и пора ли переконвертировать файлы

В llama.cpp открыт PR #31028: при конвертации Qwen в GGUF тензоры объединяются на этапе конвертации. Разбираем, что это значит для существующих GGUF и когда пер

Коротко

Что будет в материале

  1. 01

    Что произошло: PR #31028 в llama.cpp

  2. 02

    Как работает конвертация Qwen в GGUF и что значит «слияние тензоров»

  3. 03

    Кому важно следить за PR #31028, а кому можно не спешить

  4. 04

    Как проверить, актуален ли ваш GGUF-файл Qwen

Что произошло: PR #31028 в llama.cpp

В репозитории ggml-org/llama.cpp открыт пул-реквест #31028. Автор, участник под ником am17an, назвал его «qwen: merge tensors on convert». Суть в одной фразе: тензоры объединяются на этапе конвертации моделей Qwen в GGUF. Публикация с этим заголовком и вопросом о судьбе готовых файлов появилась в сообществе (обсуждение PR #31028).

Статус важнее деталей. Это открытый PR: не смерженное изменение, не релиз и не официальная рекомендация что-либо делать с архивами. Для тех, кто ставит llama.cpp из готовых сборок или пакетов, поведение инструмента на момент публикации не изменилось.

Вопрос «...time to reconvert GGUFs?» задал автор публикации в сообществе, пользователь /u/jacek2023. Обсуждение отражает частный случай: изменение в конвертере заставляет задуматься о файлах, которые уже лежат на диске. Ответ зависит от того, как именно у вас появились GGUF с Qwen.

Кто такой am17an и что именно заявлено в PR

am17an уже отправлял изменения в llama.cpp, в том числе по части внимания и Qwen (разбор PR #28770 про разреженный Flash Attention для Qwen4 на CUDA). Нынешний PR меняет работу конвертера, а не кода инференса.

Что в источнике есть: номер PR, репозиторий ggml-org/llama.cpp, автор am17an, формулировка «merge tensors on convert» и привязка к семейству Qwen. Чего в источнике нет: перечня конкретных тензоров, описания влияния на уже существующие GGUF, цифр по размеру, скорости или качеству, инструкций по проверке файлов. Все практические шаги ниже опираются на общее устройство GGUF и llama.cpp, а не на текст PR. Эту границу стоит держать в голове, чтобы не приписать изменению чужие обещания.

Почему вопрос о переконвертации вообще возник

Конвертер стоит между исходными весами и готовым файлом. Если меняется то, что он делает с тензорами, файлы, собранные старым кодом, могут отличаться по внутренней структуре от того, что выдаёт новый код. Отсюда и вопрос: не пора ли обновить архивы.

Универсального ответа нет, он зависит от роли читателя. Тот, кто качает готовые GGUF у публикатора, получит новую структуру только когда публикатор пересоберёт и перезальёт файлы. Тот, кто конвертирует сам, увидит разницу сразу после обновления llama.cpp до версии с этим PR. Ни в том, ни в другом случае источник не объявляет обязательной миграции.

Как работает конвертация Qwen в GGUF и что значит «слияние тензоров»

Цепочка выглядит так: исходные веса Qwen (набор safetensors плюс конфиги и файлы токенизатора) -> скрипт конвертации из llama.cpp -> файл .gguf с метаданными и тензорами -> запуск через llama.cpp или совместимый раннер. Каждый шаг делает отдельный инструмент, и изменение на одном шаге видно на следующем.

Тензор это многомерный массив чисел, то есть блок весов модели. «Слияние тензоров на этапе конвертации» означает, что объединение выполняет именно конвертер: он читает несколько массивов из исходного чекпоинта и записывает в GGUF один объединённый. Рантайм получает готовую структуру и ничего не склеивает на ходу.

Какие именно тензоры Qwen объединяются в #31028, источник не сообщает, это видно только в диффе PR. Название говорит о месте изменения (конвертер), не о его эффекте.

Где в цепочке находится конвертер и почему это важно

Всё сводится к вопросу «кто собрал ваш файл». Скачанный GGUF это результат чужой конвертации: структура и метаданные зафиксированы в момент сборки у публикатора. Локально собранный файл зависит от вашей версии llama.cpp на момент конвертации. Изменение в конвертере задевает вторую категорию сразу, а первую только через чужие пересборки.

Проверить свою категорию можно по одному признаку: лежат ли на диске исходные веса Qwen и запускали ли вы скрипт конвертации. Если нет, вы потребитель чужой сборки, и обновлять вам нечего.

Что PR не утверждает

В описании изменения нет ни одного из пунктов, которые обычно приписывают таким новостям:

  • уменьшение или рост размера GGUF;
  • ускорение или замедление инференса;
  • изменение качества ответов модели;
  • поломку или, наоборот, улучшение совместимости со старыми сборками.

Если в других обсуждениях вы встретите подобные заявления, к этому PR они отношения не имеют. Пока нет мержа и публичных замеров, говорить о выигрыше в скорости или качестве не на чем.

Кому важно следить за PR #31028, а кому можно не спешить

Конвертируете Qwen сами. Для вас изменение напрямую меняет пайплайн: стоит прочитать дифф, следить за мержем и при обновлении перепроверить воспроизводимость сборки. Практический вопрос здесь один: совпадает ли результат нового конвертера с тем, что вы ожидаете от своей модели.

Скачиваете готовые GGUF у публикатора. Пересобирать нечего, структура файла задана чужим конвертером. Ориентир - дата релиза и поведение самой сборки: готовый GGUF сам по себе ещё не гарантирует поддержки архитектуры в вашем рантайме (как проверять статус Qwen в llama.cpp до локального запуска).

Просто запускаете уже скачанное. До мержа PR и до появления сборок с ним для вас ничего не меняется. Ваши файлы работают так же, как работали.

Как проверить, актуален ли ваш GGUF-файл Qwen

Проверка строится на четырёх шагах, и ни один из них не требует выдуманных команд.

  1. Вспомнить или найти источник файла: скачан у публикатора или сконвертирован вами.
  2. Посмотреть метаданные GGUF и зафиксировать, что там сказано о модели и архитектуре.
  3. Сверить дату файлов и версию llama.cpp, которой они создавались, если эта информация сохранилась.
  4. Открыть PR #31028 и его дифф, чтобы понять, затрагивает ли изменение вашу модель Qwen.

Что смотреть в метаданных GGUF

GGUF хранит блок метаданных (описание модели, архитектура, параметры) и сами тензоры. Состав полей зависит от конвертера и его версии, поэтому отдельного поля «версия конвертера» там может не оказаться. Практический минимум: посмотреть, что файл сообщает об архитектуре и имени модели, и сверить с ожидаемым. Утилиты из репозитория llama.cpp умеют печатать метаданные GGUF; если под рукой их нет, остаются дата файла и источник загрузки.

Имя вроде Q4_K_M описывает тип квантизации по соглашению об именовании и не гарантирует содержимое (как проверить реальный уровень сжатия в GGUF-кванте). Для Qwen это значит: по имени архива нельзя понять, каким конвертером он собран.

Если файл взят из релиза, полезно сравнить его с оригиналом по хешу и дате: расхождения показывают, что публикатор перезаливал сборку (как проверять тихие обновления GGUF по SHA-256 и дампу метаданных).

Как читать дифф PR, если вы не контрибьютор

Откройте PR #31028 и посмотрите список изменённых файлов. Ориентир простой: затронут ли скрипт конвертации, какие функции в нём меняются, упоминаются ли конкретные архитектуры или префиксы имён тензоров Qwen. Если правки сосредоточены в конвертере, значит формат файла и код инференса сами по себе не переписываются.

Стоит прочитать и комментарии под PR: там обычно всплывают вопросы о совместимости с уже собранными файлами. Учитывайте, что комментарии это мнения участников, а не заявления автора изменения.

Когда переконвертация Qwen в GGUF имеет смысл, а когда - нет

Переконвертация оправдана, если совпадает хотя бы одно условие:

  • вы конвертируете Qwen сами, и PR уже присутствует в вашей ветке кода;
  • вам нужно повторить поведение новой логики конвертации, например для сравнения двух сборок;
  • исходные веса и запас по времени и месту на диске у вас есть.

Переконвертация не нужна, если:

  • вы пользуетесь готовыми GGUF от публикатора и модель работает;
  • PR ещё не смержен;
  • исходных весов нет, а качать их ради изменения с неописанным эффектом нерационально.

Отдельно проговорим главное: PR не обещает, что новый файл окажется лучше, быстрее или компактнее. Переконвертация меняет способ сборки и ничего не гарантирует по результату.

Издержки и риски переконвертации

Исходные веса в safetensors занимают заметно больше места, чем квантованный GGUF, и их придётся где-то хранить. Сама конвертация и повторное квантование расходуют время процессора, иногда ощутимое. Старые файлы лучше держать рядом для откатa, то есть диск расходуется дважды.

Риск в другом: собрать GGUF на промежуточной версии кода легко, а понять, почему поведение файла отличается от предыдущей сборки, без прямого сравнения трудно. Рабочие файлы не удаляйте, пока новый вариант не проверен на ваших промптах.

Что делать, если вы не хотите ничего трогать

Ничего не делать - допустимый вариант. Обязательной миграции источник не объявляет, ваши текущие GGUF с Qwen остаются рабочими, пока вы сами не решите обновить llama.cpp и пересобрать файлы. Достаточно иногда смотреть на релизы llama.cpp и на статус PR, чтобы вернуться к вопросу, когда появятся подтверждённые изменения.

Практический план: что сделать сейчас

  1. Определите происхождение файлов: скачаны у публикатора или собраны вами. Это решает, есть ли что переконвертировать в принципе.
  2. Зафиксируйте текущее состояние: версию llama.cpp, имена и даты файлов GGUF. Ничего не удаляйте.
  3. Откройте PR #31028, посмотрите изменённые файлы и обсуждение, чтобы понять, затрагивает ли изменение вашу модель Qwen.
  4. Дождитесь мержа и релиза, прежде чем менять пайплайн. Открытый PR это ещё не поведение вашей сборки.
  5. Если конвертируете сами, соберите тестовый файл на копии и сравните с текущим по измеримым вещам: загрузка, потребление памяти, ответы на ваши промпты. Незаявленных улучшений не ждите.
  6. Проверьте, не появились ли у публикатора вашей сборки перезалитые GGUF, и только после этого решайте, скачивать ли новую версию.

Материал опирается на содержимое PR #31028 и обсуждение в сообществе. Детали изменения проверяйте в самом PR: только там видно, какие тензоры Qwen объединяются и как это устроено в коде.

Подписаться на канал