Documentação

Notas de conversão

Esta página descreve a exportação Core ML normal. O grafo ANE reescrito em separado e a paletização de pesos opcional são documentados em ANE_ENGINEERING.md.

A exportação carrega checkpoints originais do Laya em módulos PyTorch FP32, verifica estritamente todas as chaves do state dict, traça uma implementação apenas de inferência e guarda um ML Program do Core ML. Os próprios ficheiros de checkpoint publicados contêm predominantemente tensores FP16; FP32 aqui descreve o cálculo de exportação/referência, não pesos de origem de maior precisão. Não é realizado nenhum treino, poda ou quantização de pesos. FP16 é uma escolha de precisão de conversão; FP32 pode ser selecionado para diagnósticos.

O runtime usa o tokenizer do checkpoint, o layout do prompt, os marcadores de opção, o embedding do tipo de pergunta, a cabeça de decisão, a cabeça de ação e as temperaturas de calibração. Choice, score, noul, critérios estruturados, contabilização de tokens e zero tokens gerados seguem a API do upstream. O codificador é bidirecional: cada pergunta continua a executar a sua própria sequência no codificador. Não há cache de estado oculto partilhado.

Escolhas de conversão validadas

  • coremltools==9.0, torch==2.7.0, numpy==2.1.3, Python 3.12.
  • Tracing TorchScript com verificação do grafo, modo de avaliação, pesos originais carregados em módulos FP32.
  • ML Program, alvo de implementação macOS 15 / iOS 18. A execução real foi testada num M3 Max com macOS 27.2; a execução em iPhone/iPad e em macOS mais antigo não foi testada.
  • Os comprimentos de sequência predefinidos são selecionados entre 16, 32, 64, 96, 128, 192, 256, 384, 512, 768, 1024, limitados pelo limite de contexto do checkpoint. O runtime preenche até ao menor comprimento disponível e mascara os tokens acrescentados.
  • O tamanho de lote predefinido é um, com 32 slots de marcador. Mais perguntas correm em blocos. --batch-size e --max-options produzem assinaturas exportadas diferentes.
  • Há formas fixas disponíveis para uma carga de trabalho conhecida. Entradas que excedam o comprimento ou a capacidade de opções de uma exportação geram um erro; não são truncadas silenciosamente para caber numa exportação menor. O truncamento de contexto do checkpoint original é preservado.

A Apple documenta a conversão TorchScript e as formas de entrada enumeradas. Várias entradas enumeradas precisam do mesmo número de formas, emparelhadas por índice; esta exportação emparelha os IDs de entrada e as máscaras de atenção em conformidade.

Falhas mantidas para reprodutibilidade

Estas são observações nesta máquina e SO, não afirmações sobre todas as versões do Core ML.

  1. O operador booleano __or__ do PyTorch não foi convertido. torch.logical_or / torch.logical_and explícitos preservam a mesma semântica de máscara.
  2. O NumPy 2.5 rejeitou uma conversão de array para escalar obsoleta dentro do coremltools 9.0. A dependência suportada do projeto está fixada abaixo do NumPy 2.2. O PyTorch foi fixado na versão 2.7.0 testada pelo conversor, em vez da 2.7.1.
  3. RangeDim com CPU_AND_GPU forçado produziu grandes erros numéricos e resultados diferentes em entradas idênticas repetidas. A exportação SDPA original coincidiu apenas em 47/63 respostas de referência, e a atenção explícita matmul/softmax coincidiu em 20/63. FP32 não resolveu a falha GPU observada com entradas curtas. CPU / seleção automática deu saídas corretas para o grafo SDPA.
  4. Os comprimentos enumerados restauraram a fidelidade e a repetibilidade da GPU. Um pequeno teste de regressão separado expôs depois um SIGTRAP do compilador MPSGraph ao fatiar uma matriz constante booleana de atenção local. O diagnóstico indicou ElementsAttr::getValues<bool> / FoldStridedSliceOp.
  5. A implementação final fatia posições inteiras e constrói a máscara booleana local depois. Isto remove a armadilha do compilador. Não cura a falha GPU geral do RangeDim: a experiência subsequente ainda coincidiu apenas em 49/63 e não foi repetível. Os comprimentos enumerados continuam a ser o padrão.

O runtime rejeita RangeDim + cpu_gpu a menos que seja explicitamente permitido para uma experiência de diagnóstico. Para reproduzir essa configuração falhada:

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

Espera-se que o teste falhe no ambiente medido. Os relatórios em bruto falhados e bem-sucedidos são mantidos em benchmarks/results/; os relatórios que contêm "passed": false não podem ser citados como configurações validadas.

Evidência de dispositivo

CPU_AND_NE significa que a CPU e o Neural Engine são permitidos, não que todos os operadores correm no Neural Engine. O benchmark regista os dispositivos preferidos/suportados e os custos estimados do plano de cálculo do Core ML. Este é um plano previsto, não um traço de hardware em runtime do Instruments, uma medição de potência ou uma prova de execução exclusiva no Neural Engine.

Carregar snapshots do Hub

O smoke test da versão encontrou um problema de empacotamento separado: carregar um ficheiro de pesos com ligação simbólica da cache partilhada do Hugging Face fez o compilador nativo do Core ML reportar um model.mlmodelc/weights/weight.bin em falta. Todos os seis pacotes locais equivalentes carregaram com êxito. O runtime copia agora os pacotes suportados por ligações simbólicas para uma cache endereçada por conteúdo de ficheiros regulares antes de construir o MLModel. Os hashes são verificados antes e depois da cópia e na reutilização; uma cache alterada ou danificada gera um erro. Os pacotes locais de ficheiros regulares não seguem este caminho de cópia. Vê USAGE.md para a localização e a substituição da cache.

Reprodutibilidade

Cada exportação inclui coreml_config.json: SHA256 dos pesos originais, revisão de origem, formas, precisão, implementação da atenção, versões das ferramentas, hora de conversão e hashes de cada ficheiro de pacote/tokenizer/configuração. As exportações recusam-se a sobrescrever diretórios existentes. Uma exportação falhada remove apenas o seu diretório de saída recém-criado.

A referência golden consolidada foi gerada a partir da revisão 573e5b62696ba441230cd6be71d593331b5d23af do Laya upstream não modificada, usando PyTorch MPS em FP32. Inclui os IDs de tokens de entrada completos e logits não arredondados. A validação compara esses tokens exatamente e verifica as respostas selecionadas, as probabilidades calibradas, as probabilidades de ação, a contabilização de tokens e os resultados públicos repetidos.

Para regenerar a referência golden num ambiente compatível com o 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

As dependências exatas da referência são registadas no JSON gerado. São separadas do ambiente de exportação fixado; o Transformers não é uma dependência de runtime nem de exportação do laya-coreml.