Документация

Заметки о конвертации

Эта страница описывает обычный экспорт Core ML. Отдельно переписанный граф ANE и опциональная палетизация весов описаны в ANE_ENGINEERING.md.

Экспорт загружает исходные контрольные точки Laya в модули PyTorch FP32, строго проверяет все ключи state-dict, трассирует реализацию только для инференса и сохраняет ML Program для Core ML. Опубликованные файлы контрольных точек сами по себе содержат преимущественно тензоры FP16; FP32 здесь описывает вычисления экспорта/эталона, а не более точные исходные веса. Обучение, прунинг и квантование весов не выполняются. FP16 — это выбор точности конвертации; FP32 можно выбрать для диагностики.

Рантайм использует токенизатор, разметку промпта, маркеры вариантов, эмбеддинг типа вопроса, голову решений, голову действий и температуры калибровки из контрольной точки. Choice, score, noul, структурированные критерии, учёт токенов и ноль сгенерированных токенов следуют upstream API. Энкодер двунаправленный: каждый вопрос всё равно прогоняет собственную последовательность энкодера. Общего кэша скрытых состояний нет.

Проверенные варианты конвертации

  • coremltools==9.0, torch==2.7.0, numpy==2.1.3, Python 3.12.
  • Трассировка TorchScript с проверкой графа, режим evaluation, исходные веса загружены в модули FP32.
  • ML Program, целевая платформа macOS 15 / iOS 18. Фактическое исполнение тестировалось на M3 Max под macOS 27.2; исполнение на iPhone/iPad и более старых macOS не тестировалось.
  • Длины последовательностей по умолчанию выбираются из 16, 32, 64, 96, 128, 192, 256, 384, 512, 768, 1024, ограничиваясь лимитом контекста контрольной точки. Рантайм дополняет до наименьшей доступной длины и маскирует добавленные токены.
  • Размер батча по умолчанию — один, с 32 слотами маркеров. Большее число вопросов идёт порциями. --batch-size и --max-options дают разные экспортированные сигнатуры.
  • Для известной рабочей нагрузки доступны фиксированные формы. Входы, превышающие длину или ёмкость вариантов экспорта, вызывают ошибку; они не усекаются молча, чтобы уместиться в меньшем экспорте. Усечение контекста исходной контрольной точки сохраняется.

Apple документирует конвертацию TorchScript и перечислимые формы входов. Несколько перечислимых входов требуют одинакового числа форм, сопоставленных по индексу; этот экспорт сопоставляет ID входов и маски внимания соответственно.

Ошибки, сохранённые для воспроизводимости

Это наблюдения на данной машине и ОС, а не утверждения о любой версии Core ML.

  1. Логический оператор PyTorch __or__ не был сконвертирован. Явные torch.logical_or / torch.logical_and сохраняют ту же семантику маски.
  2. NumPy 2.5 отклонил устаревшее преобразование массива в скаляр внутри coremltools 9.0. Поддерживаемая зависимость проекта закреплена ниже NumPy 2.2. PyTorch был закреплён на протестированной конвертером версии 2.7.0 вместо 2.7.1.
  3. RangeDim с принудительным CPU_AND_GPU дал большие числовые ошибки и разные результаты при повторных идентичных входах. Исходный экспорт SDPA совпал только с 47/63 эталонными ответами, а явное внимание matmul/softmax — с 20/63. FP32 не устранил наблюдавшийся сбой GPU на коротких входах. Выбор CPU / автоматический дал корректные выходы для графа SDPA.
  4. Перечислимые длины восстановили точность и повторяемость на GPU. Отдельный крошечный регрессионный тест затем вскрыл SIGTRAP компилятора MPSGraph при срезе константной булевой матрицы локального внимания. В диагностике указано ElementsAttr::getValues<bool> / FoldStridedSliceOp.
  5. Финальная реализация срезает целочисленные позиции и строит булеву локальную маску после этого. Это убирает ловушку компилятора. Это не лечит общий сбой RangeDim на GPU: последующий эксперимент всё ещё совпал лишь с 49/63 и не был воспроизводим. Перечислимые длины остаются значением по умолчанию.

Рантайм отклоняет RangeDim + cpu_gpu, если это явно не разрешено для диагностического эксперимента. Чтобы воспроизвести эту неудачную конфигурацию:

laya-coreml convert laya-multilingual models/range-experiment --shape-mode range
python -m benchmarks.validate models/range-experiment \
  --name laya-multilingual --compute-units cpu_gpu --allow-unvalidated-gpu \
  --repeats 10 --output artifacts/range-experiment.json

Ожидается, что тест завершится неудачей на измеряемом окружении. Сырые отчёты о неудачах и успехах сохранены в benchmarks/results/; отчёты, содержащие "passed": false, нельзя приводить как проверенные конфигурации.

Свидетельства об устройстве

CPU_AND_NE означает, что CPU и Neural Engine разрешены, а не что каждый оператор исполняется на Neural Engine. Бенчмарк записывает предпочитаемые/поддерживаемые устройства и оценки стоимости из плана вычислений Core ML. Это предполагаемый план, а не трасса оборудования из Instruments, не измерение мощности и не доказательство эксклюзивного исполнения на Neural Engine.

Загрузка снимков Hub

Дымовой тест выпуска обнаружил отдельную проблему упаковки: загрузка файла весов по символической ссылке из общего кэша Hugging Face приводила к тому, что нативный компилятор Core ML сообщал об отсутствии model.mlmodelc/weights/weight.bin. Все шесть эквивалентных локальных пакетов загрузились успешно. Теперь рантайм копирует пакеты, основанные на символических ссылках, в адресуемый по содержимому кэш обычных файлов перед созданием MLModel. Хеши проверяются до и после копирования и при повторном использовании; изменённый или повреждённый кэш вызывает ошибку. Локальные пакеты из обычных файлов не идут по этому пути копирования. Расположение кэша и способ его переопределения см. в USAGE.md.

Воспроизводимость

Каждый экспорт включает coreml_config.json: SHA256 исходных весов, ревизию исходников, формы, точность, реализацию внимания, версии инструментов, время конвертации и хеши каждого файла пакета/токенизатора/конфигурации. Экспорты отказываются перезаписывать существующие каталоги. Неудачный экспорт удаляет только свой заново созданный выходной каталог.

Закоммиченный эталон сгенерирован из неизменённой upstream-ревизии Laya 573e5b62696ba441230cd6be71d593331b5d23af с использованием FP32 PyTorch MPS. Он включает полные ID входных токенов и неокруглённые логиты. Валидация сравнивает эти токены точно и проверяет выбранные ответы, калиброванные вероятности, вероятности действий, учёт токенов и повторяемые публичные результаты.

Чтобы перегенерировать эталон в среде, совместимой с upstream:

git clone https://github.com/NandhaKishorM/laya .upstream
git -C .upstream checkout 6a5819129eb220570792e417e49723d697efd76f
python -m benchmarks.reference --upstream .upstream --model-root /path/to/original/checkpoints

Точные зависимости эталона записаны в сгенерированном JSON. Они отдельны от закреплённого окружения экспорта; Transformers не является зависимостью рантайма или экспорта laya-coreml.