Core ML
Core ML é o formato de modelos on-device da Apple. O LibreYOLO traça o detector por trás de um wrapper de pré-processamento específico de cada família, de modo que o grafo convertido sempre recebe uma entrada de imagem RGB canônica, e então escreve um .mlpackage em formato ML Program com os metadados do modelo anexados.
- Flag
export(format="coreml")- Escreve
- Um bundle .mlpackage (um diretório) em formato ML Program
- Extra
pip install "libreyolo[coreml]"- Recarrega com
LibreYOLO("weights/LibreYOLO9t.mlpackage") no macOS- Formas
- Fixas. A entrada é um ct.ImageType de forma rígida.
- Precisão
- FP32, FP16 (half=True). Sem INT8.
- Famílias
- Somente detecção, para yolox, yolo9, rtdetr e rfdetr
Instalação
pip install "libreyolo[coreml]"A predição precisa de macOS. LibreYOLO() recusa um .mlpackage em qualquer outra
plataforma com uma mensagem nomeando a plataforma atual, e a matriz de suporte registra
essas combinações como disponíveis porque a paridade de runtime exige um runner macOS.
Exportação
from libreyolo import LibreYOLO model = LibreYOLO("LibreYOLO9t.pt") # Escreve o bundle weights/LibreYOLO9t.mlpackagepath = model.export(format="coreml")print(path)libreyolo export --model LibreYOLO9t.pt --format coremlmodel.export( format="coreml", imgsz=640, batch=1, half=False, # True converte com precisão de cálculo FLOAT16 compute_units="all", # all | cpu_and_gpu | cpu_and_ne | cpu_only output_path=None, # None escreve weights/<stem>.mlpackage) # dynamic é aceito, mas a entrada é um ct.ImageType de forma fixa,# e os metadados embutidos registram dynamic=False de qualquer jeito.O bundle é escrito em weights/ com o nome-base do checkpoint, com _fp16
acrescentado quando half=True. Um .mlpackage é um diretório, então copie a árvore inteira.
Toda família é traçada por trás de um wrapper de pré-processamento, de modo que o grafo
convertido recebe uma única entrada canônica: RGB, scale=1/255, sem bias, declarada como
ct.ImageType. O wrapper absorve a convenção própria da família, que é BGR na
faixa de 0 a 255 para o YOLOX, média e desvio padrão do ImageNet para o RF-DETR,
e identidade para o YOLO9 e o RT-DETR. É por isso que um consumidor Core ML recebe uma
imagem comum em vez de um tensor específico da família.
A conversão tem como alvo o ML Program com um deployment target mínimo de iOS 15.
compute_units fica armazenado no modelo convertido e pode ser sobrescrito de novo quando
o artefato é carregado.
Os metadados do modelo vão para user_defined_metadata como strings, que é de onde o
backend lê a família, a tarefa, os nomes das classes, o tamanho de entrada e o esquema de pose.
NMS embutido
from libreyolo import LibreYOLO # Somente detecção com YOLOX e YOLO9, batch 1.LibreYOLO("LibreYOLO9t.pt").export( format="coreml", nms=True, conf=0.25, iou=0.45,)libreyolo export --model LibreYOLO9t.pt --format coreml --nms \ --conf 0.25 --iou 0.45nms=True envolve o modelo em um pipeline do Core ML que termina na camada
NonMaximumSuppression da Apple. O resultado tem duas saídas: confidence, com formato
N pela contagem de classes, e coordinates, com formato N por 4 como xywh normalizado.
Vale somente para detecção com YOLOX e YOLO9, e exige batch 1. As
famílias no estilo DETR são recusadas pelo nome, porque a predição de conjunto faz um top-k sobre
queries e classes sem nenhuma etapa de IoU e não consegue usar essa camada. max_det também não é
exposto aqui; quando o limite de detecções importa, use o
NMS embutido do ONNX em vez disso.
Rodar o artefato
from libreyolo import LibreYOLO, SAMPLE_IMAGE model = LibreYOLO( "weights/LibreYOLO9t.mlpackage", compute_units="all", # ou cpu_and_ne para fixar o Neural Engine)result = model.predict(SAMPLE_IMAGE)print(result.boxes.xyxy[:3])import coremltools as ctfrom PIL import Image mlmodel = ct.models.MLModel("weights/LibreYOLO9t.mlpackage")print(mlmodel.user_defined_metadata["model_family"])print(mlmodel.user_defined_metadata["names"]) # A entrada é uma imagem chamada "image" no tamanho fixo da exportação.image = Image.open(SAMPLE_IMAGE).convert("RGB").resize((640, 640))out = mlmodel.predict({"image": image})print({name: value.shape for name, value in out.items()}) # O letterboxing e o pós-processamento ficam por sua conta neste caminho.LibreYOLO() reconhece um diretório com o sufixo .mlpackage e devolve o
mesmo objeto Results que o checkpoint. compute_units é o único argumento que a
factory repassa para este formato, e ele aceita all, cpu_and_gpu,
cpu_and_ne e cpu_only. O argumento device é ignorado, porque o Core ML
roteia por compute units.
O segundo snippet é o caminho do runtime puro. O letterboxing, a decodificação, o NMS e o
reescalonamento de coordenadas ficam por sua conta ali, e os nomes das classes vivem em
user_defined_metadata.
Restrições
Quatro famílias, somente detecção: yolox, yolo9, rtdetr e rfdetr. Qualquer outra
coisa é recusada no preflight, porque o wrapper de pré-processamento ciente da família é
o que torna correto o contrato de entrada de imagem fixa, e uma família fora dele
converteria com a normalização errada. O erro nomeia ONNX e TorchScript como
alternativas.
O formato de entrada é fixado de forma rígida por ct.ImageType, então dynamic=True não muda nada
e os metadados registram dynamic=False. Exporte um segundo bundle para uma segunda
resolução.
half=True converte com precisão de cálculo FP16. Não existe caminho para INT8 a partir deste
exportador.
Para a grade completa de famílias e tarefas, veja a matriz de exportação. Para o formato on-device mais recente da Apple, veja Core AI. Para uma combinação:
libreyolo formats --family yolo9 --task detect