Inferência on-device com Core ML: os padrões que realmente entram em produção
O Core ML é o motor de inferência on-device que vem em todo dispositivo Apple moderno. O framework despacha para o Neural Engine quando disponível, para a GPU quando não, e para a CPU como último recurso, escolhendo o caminho mais rápido automaticamente com base no modelo e no hardware1. O resultado em um iPhone recente é inferência com latência de submilissegundos a dezenas de milissegundos para a maioria dos tamanhos de modelo de produção, gratuita por chamada, sem roundtrip de rede e sem exposição de dados a terceiros.
A reputação do framework como “encanamento obscuro” está datada. O Core ML hoje alimenta o LLM on-device do Apple Intelligence, a busca semântica do app Fotos, o reconhecimento de cena do app Câmera e a maioria dos apps de terceiros que entregam ML local. Os padrões que fazem uma implantação Core ML realmente entrar em produção, em vez de apenas funcionar-na-minha-máquina, são um conjunto pequeno: conversão de modelo, hinting de dispatch, orçamento de latência e quantização. O post percorre cada um deles em comparação com a documentação da Apple.
TL;DR
- O Core ML executa arquivos
.mlpackagee.mlmodelno Neural Engine, na GPU e na CPU do Apple Silicon. O dispatch é automático, mas pode receber hints viaMLModelConfiguration.computeUnits2. - A conversão de modelo acontece via
coremltools(PyTorch, TensorFlow, ONNX → Core ML). A conversão é uma tarefa de tooling, não de runtime; uma vez convertido e empacotado, o app carrega e executa o modelo. - A arquitetura de memória unificada do Apple Silicon significa que os pesos do modelo não são copiados entre CPU, GPU e NE; a mesma memória dá suporte aos três3. Esse detalhe arquitetural é o que torna possível a inferência em submilissegundos.
- A quantização (INT8, INT4 em versões recentes do Core ML) reduz o tamanho do modelo e acelera a inferência no Neural Engine, com um custo mensurável de acurácia que depende do modelo.
- A conexão com agent workflows: Foundation Models (o LLM on-device do Apple Intelligence) é entregue como um modelo Core ML por trás de uma API Swift de alto nível; os mesmos padrões de dispatch e quantização se aplicam.
O modelo mental: três caminhos de compute, uma memória
O Apple Silicon (Macs da série M e iPhones da série A a partir do A12 Bionic) traz três alvos de inferência:
Neural Engine. Um acelerador especializado para multiplicação de matrizes em baixa precisão. O mais rápido para as operações das quais os modelos modernos de ML dependem (convoluções, attention, embeddings). Menor consumo de energia. Limitado a tipos específicos de operação e formatos de tensor; ops não suportadas caem para GPU ou CPU camada por camada.
GPU. Compute paralelo de propósito geral via Metal. Mais lento que o Neural Engine para trabalho com formato de ML, mas mais rápido que CPU. Lida com operações que o Neural Engine não suporta.
CPU. O fallback. Lento para inferência de ML, mas sempre disponível, sempre suporta toda operação e é previsível.
A arquitetura de memória unificada significa que a mesma RAM física dá suporte aos três3. Os pesos de um modelo, carregados uma vez, não são copiados quando o dispatch muda entre alvos. Esse fato arquitetural é o que transforma o dispatch multi-alvo de um custo de cópia por camada em uma decisão de scheduling por camada.
MLModelConfiguration.computeUnits controla o dispatch:
let config = MLModelConfiguration()
config.computeUnits = .all // default: NE, GPU, CPU
// Other options:
// .cpuAndGPU
// .cpuAndNeuralEngine
// .cpuOnly
let model = try MyModel(configuration: config)
.all é o default e a escolha certa para quase todo app. O framework escolhe o caminho mais rápido por operação, e a decisão por operação é mais rápida do que qualquer heurística que o desenvolvedor escreveria. A razão rara para sobrescrever é forçar .cpuOnly para teste de paridade (um modelo se comporta de forma diferente em caminhos diferentes e o teste quer o caminho determinístico) ou forçar .cpuAndGPU para liberar o Neural Engine para outra tarefa concorrente.
Conversão de modelo: a tarefa de tooling
A maioria dos modelos de ML é treinada em PyTorch, TensorFlow ou diretamente via Create ML da Apple. O Core ML aceita arquivos .mlpackage, o formato moderno introduzido no Xcode 13 que substitui o antigo .mlmodel4. A conversão acontece via coremltools, o pacote Python open-source da Apple5.
Uma conversão típica de PyTorch para Core ML segue três passos:
- Carregar o modelo PyTorch treinado e colocá-lo em modo de inferência.
- Fazer trace do modelo com um tensor de entrada de exemplo correspondente ao formato de entrada de produção.
- Converter o modelo traçado com
coremltoolscontra uma versão de iOS de implantação alvo.
import torch
import coremltools as ct
model = MyTrainedModel()
model.load_state_dict(torch.load("weights.pth"))
example_input = torch.rand(1, 3, 224, 224)
traced_model = torch.jit.trace(model, example_input)
mlmodel = ct.convert(
traced_model,
inputs=[ct.ImageType(name="image", shape=example_input.shape)],
minimum_deployment_target=ct.target.iOS18,
compute_units=ct.ComputeUnit.ALL,
)
mlmodel.save("MyModel.mlpackage")
A conversão acontece uma vez, em um ambiente de desenvolvimento, contra uma versão de iOS de implantação alvo (minimum_deployment_target). O .mlpackage resultante é o que vai para o projeto Xcode. O app em runtime não executa coremltools.
Duas armadilhas práticas na conversão. Primeiro, entradas com formato dinâmico precisam de tratamento explícito via ct.RangeDim porque o default de formato estático do Core ML produz erros pouco úteis quando o app de produção alimenta tamanhos de entrada variados. Segundo, ops customizadas em PyTorch que não têm equivalente no Core ML precisam de uma camada custom do Core ML (código Swift que executa a op faltante) ou de uma mudança na arquitetura do modelo para remover a op antes da conversão. Ambas estão bem documentadas5.
Orçamentos de latência que realmente se aplicam
Três orçamentos de latência importam para apps em produção:
16 ms (UI ao vivo a 60 fps). Um filtro de câmera em tempo real, uma cena de AR que atualiza por frame, um analisador de áudio ao vivo. O orçamento inclui tudo: pré-processamento de imagem, inferência do modelo, pós-processamento, atualização de UI. Modelos que cabem são tipicamente pequenos (classe MobileNetV3, sub-100M de parâmetros) e rodam no Neural Engine.
100 ms (UI interativa). O usuário faz uma ação e espera o resultado: tocar para identificar, desenhar para reconhecer, ditar para transcrever. O orçamento é mais permissivo e suporta modelos maiores. Modelos de linguagem com menos de 1B de parâmetros, vision transformers pequenos e a maioria dos classificadores de qualidade de produção cabem confortavelmente.
1 s+ (background ou batch). Indexação de biblioteca de fotos, análise de documentos, warm-up de modelo no launch do app. Modelos maiores funcionam, mas a expectativa do usuário precisa ser definida com um indicador de progresso. O LLM on-device do Foundation Models vive aqui para as operações de janela de contexto maiores.
Os orçamentos são guidelines, não limites rígidos. A jogada certa é medir em um dispositivo alvo via os_signpost ou o template Core ML do Instruments6 em vez de confiar em números teóricos de outra máquina.
Quantização: quando menor é mais rápido
O Core ML suporta vários níveis de quantização7:
- Float32 (precisão total). O default de treino. O maior, mais acurado, mais lento.
- Float16. Meia precisão. Menor e mais rápido na GPU e no NE; a perda de acurácia é geralmente desprezível para modelos bem condicionados.
- INT8. Quantização de inteiros de 8 bits com calibração. Cerca de 4x menor que Float32, frequentemente 2-4x mais rápido no NE. A perda de acurácia varia; para modelos de visão, perda de acurácia top-1 sub-1% é alcançável com treinamento ciente de quantização.
- INT4 e abaixo. Quantização agressiva que versões recentes do Core ML suportam para arquiteturas de modelo específicas (LLMs, modelos grandes de visão). Perda significativa de acurácia é o trade-off; a técnica funciona melhor quando combinada com treinamento ciente de quantização específico para o modelo.
A configuração de quantização linear via coremltools.optimize.coreml.linear_quantize_weights aceita uma config global de op que escolhe o modo de quantização (linear_symmetric ou linear) e um threshold de tamanho de peso abaixo do qual os pesos permanecem em precisão total. A conversão roda contra um .mlpackage existente e produz um novo pacote quantizado; ambos podem ser entregues lado a lado no bundle, com o app escolhendo qual carregar com base na classe do dispositivo.
A decisão de quantização é por modelo: um classificador pequeno pode não se beneficiar porque seu compute já é barato; um modelo de linguagem grande se beneficia enormemente porque seu compute é dominado por multiplicações de matriz nos pesos quantizados. A abordagem certa é quantizar, medir a acurácia em um conjunto de teste reservado e entregar se a queda de acurácia for aceitável para o caso de uso.
Modelos prontos da Apple que você pode usar diretamente
A Apple disponibiliza vários modelos Core ML pré-treinados na página Core ML Models8. Categorias que vale a pena conhecer:
- Classificação de imagens: MobileNetV2, ResNet50, variantes do SqueezeNet, todos empacotados e prontos para serem usados em uma
VNCoreMLRequestdo framework Vision. - Detecção de objetos: YOLOv3, MNIST, variantes do CenterNet.
- Estimativa de pose: PoseNet para pose corporal (uma alternativa de baseline ao
VNDetectHumanBodyPoseRequestdo Vision). - Segmentação semântica: DeepLabV3 para segmentação de imagens.
- Reconhecimento de texto: Alternativas de OCR baseadas em ML ao OCR embutido do Vision.
Para a maioria dos apps, os modelos pré-treinados da Apple cobrem as primitivas de percepção (classificar, detectar, segmentar) sem exigir treinamento custom. O LLM on-device do Foundation Models (coberto em Foundation Models on-device LLM) é o maior exemplo: um LLM de múltiplos bilhões de parâmetros entregue como modelo Core ML por trás de uma API Swift de alto nível, despachado no Neural Engine, disponível offline.
Criptografia de modelo e considerações sobre App Store
Um .mlpackage no bundle do app é legível por qualquer um que descompacte o IPA. Para modelos que representam propriedade intelectual significativa, a Apple suporta criptografia de modelo via o workflow Encrypt your Core ML model9: uma chave de criptografia é gerada via Xcode e gerenciada via CloudKit, o modelo no bundle é criptografado e o Core ML descriptografa em tempo de carregamento.
Para a maioria dos apps, criptografia é exagero. Um modelo treinado em dados ImageNet de prateleira não é um diferencial competitivo; criptografá-lo adiciona complexidade operacional sem proteger nada de valor. Reserve a criptografia para modelos que representem investimento real em dados de treino ou vantagem competitiva.
Privacidade on-device: a vitória arquitetural
A história da privacidade é direta. A inferência do Core ML acontece inteiramente no dispositivo. Os dados de entrada (imagens, áudio, texto) não saem do dispositivo. O arquivo de modelo é local; a inferência é local; o resultado é local.
Para apps em indústrias reguladas (saúde, finanças, educação), esse fato arquitetural elimina uma classe inteira de trabalho de compliance. Não há processador de dados terceiro para adicionar a uma política de privacidade. Não há endpoint de API de modelo para auditar em segurança. Não há questão de residência de dados porque os dados nunca se movem.
O formato de Privacy Manifest10 codifica a história de privacidade para submissão à App Store: um app que usa Core ML para inferência on-device e nada mais pode declarar zero compartilhamento de dados com terceiros para o caminho de inferência. O processo de submissão é mais rápido, a revisão de privacidade é mais curta e o rótulo nutricional de privacidade voltado ao usuário é mais limpo.
A conexão com agent workflows
O Core ML se combina com três padrões que o cluster já cobriu:
VNCoreMLRequest do framework Vision. Modelos Core ML customizados rodam pelo pipeline do Vision com pré-processamento automático. O padrão (coberto em Vision Framework) é o jeito certo de entregar um classificador ou detector de imagens custom dentro de um app iOS.
Foundation Models on-device LLM. O LLM do Apple Intelligence é um modelo Core ML por trás de uma API Swift de alto nível. Os mesmos padrões de dispatch (Neural Engine primeiro), quantização (INT4 para os pesos do LLM) e orçamento de latência (sub-segundo para gerações curtas) se aplicam. O post sobre Foundation Models cobre a API; este post cobre o motor por baixo.
Tools do App Intents usando ML local. Um AppIntent que executa um classificador local de imagens ou de texto retorna resultados estruturados ao Apple Intelligence sem um roundtrip de rede. A combinação é o que torna a “Apple agêntica” realmente privada; as tools do agente rodam localmente porque o framework dá suporte a isso.
Quando inferência na cloud é a escolha certa
O teto do Core ML é o compute do dispositivo. Três casos em que a cloud é correta:
Modelos grandes demais para entregar em um bundle. Um LLM de 70B parâmetros não cabe em um bundle de app. Para cargas de trabalho nessa escala, inferência na cloud (ou on-device-via-streaming-de-pesos, um padrão diferente) é a ferramenta certa.
Estado compartilhado entre dispositivos durante a inferência. Modelos que precisam ler ou escrever em um banco de dados compartilhado durante a inferência (sistemas de recomendação com filtragem colaborativa contra bilhões de registros). O modelo puramente local do Core ML não se encaixa.
Iteração rápida de modelo. Um time que entrega atualizações de modelo diariamente se beneficia de inferência server-side porque os rollouts não exigem ciclos de revisão da App Store. O padrão do Core ML de empacotar-o-modelo-no-app adiciona atrito à cadência de revisão de modelo; o trade-off é real.
O padrão: a cloud vence em escala e velocidade de iteração; o Core ML vence em latência, custo e privacidade.
O que esse padrão significa para apps iOS 26+
Três conclusões.
-
Padronize o uso de Core ML para qualquer modelo que caiba no bundle e produza um resultado por chamada sobre o qual o usuário possa agir. Classificação de imagem, detecção de objetos, classificação de áudio, reconhecimento de gestos, geração de embeddings, tarefas de linguagem pequenas a médias. O dispatch automático do framework e a NPU do Apple Silicon produzem inferência de submilissegundos a dezenas de milissegundos de graça.
-
Quantize agressivamente quando a queda de acurácia for aceitável. INT8 é geralmente seguro; INT4 é apropriado para modelos grandes onde a economia de tamanho importa. Meça a acurácia em um conjunto reservado em vez de confiar que a quantização é universalmente segura.
-
Combine com Vision e Foundation Models para pipelines locais completos. O Core ML é o motor; o Vision é a API de percepção em cima dele; o Foundation Models é o LLM em cima dele. Os posts Vision e Foundation Models do cluster cobrem as superfícies de mais alto nível.
O cluster Apple Ecosystem completo: App Intents tipados; servidores MCP; a questão de roteamento; Foundation Models; a distinção LLM runtime vs tooling; três superfícies; o padrão de fonte única da verdade; Two MCP Servers; hooks para desenvolvimento Apple; Live Activities; o contrato de runtime do watchOS; internals do SwiftUI; o modelo mental espacial do RealityKit; disciplina de schema do SwiftData; padrões do Liquid Glass; shipping multi-plataforma; a matriz de plataformas; framework Vision; Symbol Effects; sobre o que me recuso a escrever. O hub está na Apple Ecosystem Series. Para contexto mais amplo de iOS com agentes de IA, veja o iOS Agent Development guide.
FAQ
Como o Core ML decide entre Neural Engine, GPU e CPU?
O Core ML examina cada operação no grafo do modelo e despacha para o alvo mais rápido que suporta a operação. O Neural Engine lida com operações suportadas (a maioria das multiplicações de matriz, convoluções, attention) com a menor latência e energia. A GPU lida com ops que o NE não suporta. A CPU lida com o resto. A decisão é por operação, automática e mais rápida do que uma heurística escrita à mão.
Devo sempre usar .computeUnits = .all?
Quase sempre. O dispatch automático do framework é bem ajustado. Sobrescreva para .cpuOnly ao testar paridade de saída (o mesmo modelo retorna resultados ligeiramente diferentes no NE vs CPU devido a arredondamento de ponto flutuante) ou para .cpuAndGPU para liberar o Neural Engine para uma tarefa concorrente.
Qual é a diferença prática entre .mlpackage e .mlmodel?
.mlpackage é o formato moderno introduzido no Xcode 13. Suporta metadados armazenados, múltiplas variantes de modelo para compilação ML Program (mlprogram) e a toolchain pós-iOS 13. .mlmodel é o formato legado. Ambos ainda carregam via MLModel; novo desenvolvimento deve usar .mlpackage.
Quão grande pode ser um modelo Core ML em um bundle de app?
Não há limite fixo, mas tamanhos de bundle da App Store são limitados a 4 GB para download e têm limites práticos para instalação over-the-air. O LLM on-device do Foundation Models tem cerca de 3 GB e é distribuído pelo OS em vez do bundle do app. Para modelos empacotados no app, sub-100 MB é confortável; 100-500 MB é viável com uma estratégia de carregamento em launch-time; 500 MB+ é melhor tratado via download em background com BGProcessingTask ou recursos sob demanda.
Como sei se a quantização prejudicou a acurácia do meu modelo?
Reserve um conjunto de teste, rode inferência no modelo Float32 original e no modelo quantizado, compare métricas (acurácia top-1 para classificadores, F1 para detectores, perplexidade para modelos de linguagem, BLEU para tradução, etc.), decida com base nos requisitos de acurácia da aplicação. O treinamento ciente de quantização (treinar o modelo com a quantização simulada na loss) geralmente recupera a maior parte da perda de acurácia.
Referências
-
Documentação Apple Developer: Core ML. Referência do framework cobrindo o comportamento de dispatch automático entre compute units. ↩
-
Documentação Apple Developer:
MLModelConfiguration.computeUnits. Casos de enum que controlam quais compute units o modelo pode usar. ↩ -
Apple Developer: Apple silicon performance (introdução da WWDC 2020 à arquitetura de memória unificada do Apple Silicon). ↩↩
-
Documentação Apple Developer: Core ML Model. Referência dos formatos
.mlpackagee.mlmodel. ↩ -
Documentação do
coremltools. Pacote Python open-source da Apple para converter modelos treinados de PyTorch, TensorFlow e ONNX para Core ML. ↩↩ -
Documentação Apple Developer: Profiling Core ML models with Instruments. O template Core ML do Instruments para análise de latência e dispatch por camada. ↩
-
Otimização do
coremltools. Técnicas de quantização e padrões de preservação de acurácia suportados pelo Core ML. ↩ -
Apple Developer: Core ML Models. Galeria da Apple de modelos pré-treinados prontos para usar em apps iOS. ↩
-
Documentação Apple Developer: Encrypting a Model in Your App. O workflow de criptografia baseado em CloudKit para modelos Core ML. ↩
-
Documentação Apple Developer: Privacy manifest files. O formato para declarar comportamentos de coleta de dados e tracking de um app. ↩