If a Core ML version of the model already exists on Hugging Face, download the .mlpackage, drag it into your Xcode project, and call the Swift class Xcode writes for it. If the model only exists as PyTorch weights, convert it with coremltools (ct.convert, then save("model.mlpackage")). If it is a language model, look at MLX Swift instead. Before any of that, read the license on the model card, because "downloadable" does not mean "free to ship". I downloaded a real Core ML model from Hugging Face for this guide, generated its Swift class with Apple's coremlcompiler, and compiled the Swift below with Xcode 27.1 (Swift 6.4) against the iOS 18 simulator SDK. The coremltools step comes from Apple's documentation and I did not run it.
Which route for which model
| Starting point | Route | What you ship |
|---|---|---|
Repo tagged coreml with an .mlpackage (for example the apple/ organization) | Download it and add it to Xcode | A compiled Core ML model in the app, or downloaded later |
| Model published as PyTorch or TensorFlow weights | Convert with coremltools, then add to Xcode | A model package you produced; check the license allows it |
| Chat or text-generation language model | MLX Swift (mlx-swift-lm) with a model from the mlx-community org | A Swift package plus a model downloaded at run time |
Route 1: a ready Core ML package
Hugging Face model cards carry metadata tags such as coreml, and Apple publishes Core ML versions of several vision models under its own apple/ organization. I picked apple/coreml-FastViT-T8, an image classifier trained on ImageNet-1k. Its card says it has 4.0 million parameters, takes a 256 x 256 image, and the Float16 package is 7.8 MB. The card's own instructions download it with the Hugging Face command line tool:
huggingface-cli download \
--local-dir models --local-dir-use-symlinks False \
apple/coreml-FastViT-T8
I fetched the same files with the huggingface_hub Python library instead; the result is the same folder, FastViTT8F16.mlpackage, plus a README.md and a LICENSE file. Check what the repo actually contains before you plan around it: some apple/ repos hold older .mlmodel files instead of packages, for example apple/coreml-resnet-50.
Add it to Xcode
Apple's sample describes the steps: drag the model into the project navigator, and open it in Xcode to see the model type and its expected inputs and outputs. Xcode then writes a Swift interface for the model, its input and its output, and compiles the model into a form optimized for the device, which is what ships in the app bundle.
You can see exactly what Xcode writes without opening Xcode. This command, run on the downloaded package, produced one Swift file:
xcrun coremlcompiler generate FastViTT8F16.mlpackage gen --language Swift
The file defines three classes for this model:
FastViTT8F16Input, with animageproperty (aCVPixelBuffer, 256 by 256) and convenience initializers that take aCGImageor a file URLFastViTT8F16Output, withclassLabel(aString) andclassLabel_probs(a[String: Double])FastViTT8F16, withload()andprediction(input:)in synchronous, completion handler andasyncforms
This code uses that generated class. I compiled it together with the generated file using the command from the next section, and it type-checks:
import CoreML
import CoreGraphics
func classify(_ image: CGImage) async throws -> (label: String, probability: Double) {
let model = try await FastViTT8F16.load()
let input = try FastViTT8F16Input(imageWith: image)
let output = try await model.prediction(input: input)
return (output.classLabel, output.classLabel_probs[output.classLabel] ?? 0)
}
I compiled it but did not run a prediction on a photo, so I have no accuracy result to report. The model card lists a 0.9 percent drop in accuracy against the original PyTorch model for this Float16 version, and inference times it measured (0.79 ms on an iPhone 12 Pro Max, 0.62 ms on an M3 Max, mostly on the Neural Engine). Those are the card's numbers, not mine.
Or load it with MLModel
Apple's docs say that in most cases you can use the wrapper class without touching MLModel, but an app that downloads and compiles a model on the user's device must use the MLModel class directly. In that case you call MLModel.compileModel(at:) on the downloaded file and open the compiled copy. This version type-checks for an iOS 18 target:
import CoreML
import Foundation
func loadModel(packageURL: URL) async throws -> MLModel {
let compiledURL = try await MLModel.compileModel(at: packageURL)
let configuration = MLModelConfiguration()
configuration.computeUnits = .all
return try await MLModel.load(contentsOf: compiledURL, configuration: configuration)
}
The check, run from the Terminal:
xcrun swiftc -typecheck -parse-as-library \
-target arm64-apple-ios18.0-simulator \
-sdk $(xcrun --show-sdk-path --sdk iphonesimulator) load.swift
I also built a small macOS command line tool around the same function and ran it on the downloaded package. It printed the model's description: input image 4 256x256, output classLabel 3 and output classLabel_probs 6 (those numbers are the raw values of Core ML's feature type enum, not sizes). computeUnits = .all lets the system choose the processing unit, including the Neural Engine if the device has one; Apple's docs say .cpuOnly is for apps that may run in the background or do other GPU-heavy work. Apple's guide on downloading models also says Core ML puts compiled models in a temporary location, so save the compiled model somewhere permanent, such as Application Support, if you want to reuse it. It also warns to think about iCloud Backup size for large models.
Route 2: convert with coremltools
When a model has no Core ML version, Apple's coremltools documentation describes two steps: capture the PyTorch model graph with torch.jit.trace (the documented stable path) or torch.export, then convert it. This is the docs' own flow, shown here without my having run it:
import torch
import torchvision
import coremltools as ct
# Load a pre-trained model and put it in evaluation mode.
torch_model = torchvision.models.mobilenet_v2(pretrained=True)
torch_model.eval()
# Trace it with an example input.
example_input = torch.rand(1, 3, 224, 224)
traced_model = torch.jit.trace(torch_model, example_input)
# Convert and save as a model package.
model = ct.convert(
traced_model,
inputs=[ct.TensorType(shape=example_input.shape)],
)
model.save("newmodel.mlpackage")
Details from the docs: since Core ML Tools 7.0, convert() produces an ML program by default, and ML programs must be saved as an .mlpackage, not an .mlmodel. The weights and intermediate values are Float16 by default, and you can ask for Float32 with compute_precision=ct.precision.FLOAT32 when Float16 is not precise enough. For image models, the docs point to ImageType inputs instead of the TensorType used above (see their Image Input and Output page). They also say the newer torch.export path covered roughly 70 percent of PyTorch operations as of Core ML Tools 8.0, so a model can fail to convert; keep test inputs from the original model and compare outputs before and after.
Route 3: language models with MLX Swift
Core ML is the right default for vision, audio and classic models. For chat-style language models, The ml-explore organization publishes mlx-swift-lm, a Swift package for building tools and apps with large language models and vision language models. Its README shows how to add it to Package.swift and which products to link, and it can load models from the Hugging Face Hub. The MLX guide covers trying the same models on your Mac first, and the mlx-swift-examples repo has an app that runs on both iOS and macOS and downloads a language model. I have not built an app with it for this guide, so I give no memory or speed figures for iPhone.
Size and memory on the device
I could find no memory table for iPhones in Apple's or Hugging Face's docs, so I will not invent one. What the sources do say:
- Bundling a model is the simplest way to start, but advanced models take significant storage. Apple suggests lower precision weights (from 32 down to 16 bits, or lower, 1 to 8 bits) through the coremltools utilities.
- If you still need a smaller download, Apple describes downloading the model after install and compiling it on the device, for example when users need only some of the models your app supports.
- The coremltools docs have separate sections on palettization, linear quantization and pruning for compressing weights.
- The model card for FastViT lists two variants, T8 at 7.8 MB and MA36 at 84 MB. Pick the smallest one that meets your quality bar, and test on the oldest device you support.
Check the license before you ship
Hugging Face says a license is set in the model card's metadata and asks you to respect it. Cards differ, and this matters for apps you sell:
apple/coreml-resnet-50is taggedmit.apple/coreml-FastViT-T8is taggedother, withlicense_name: apple-ascland aLICENSEfile in the repo. Its card says to observe the original license. "Other" means you must read the file; I did not interpret it for you.- A converted model is a derived copy, so the original model's terms follow it, and so do the terms of its training data, if the card lists any.
Write down the license, the model's repo URL and the commit you downloaded, and keep them with your release notes.
What this means for App Review and privacy
Apple's App Privacy Details page defines "collect" as transmitting data off the device in a way that lets you or your partners access it for longer than needed to service the request in real time. It also says data processed only on the device is not "collected" and does not need to be disclosed in your App Store Connect answers. So an on-device model that works on a photo and never sends it anywhere can keep that photo out of your data collection answers. Three cautions:
- The rule covers data that stays on the device. If your app also sends the photo, the result or any usage data to a server or a third-party SDK, answer for that.
- Downloading a model at run time is a network request. It sends the request itself, such as an IP address, so look at how you host it and what your host keeps.
- A privacy policy URL is still required for every app, even one that collects nothing. See Does my iOS app need a privacy policy? for the details, and describe in plain words what the model does with the user's input.
Clean up
All files for this guide lived in a scratch folder: the model (7.8 MB), the generated Swift file and a compiled copy. The whole folder was 16 MB, and nothing was added to a project.
Sources
All read on 2 November 2026.
- apple/coreml-FastViT-T8, the package, its card, license and download instructions
- apple/coreml-resnet-50, the license tag and the
.mlmodelfiles - Integrating a Core ML model into your app, adding a model and the wrapper Xcode writes
- MLModel, the wrapper class versus the
MLModelinterface - Downloading and compiling a model on the user's device,
compileModel(at:)and saving the compiled copy - Reducing the size of your Core ML app, lower precision weights and downloading models
- MLComputeUnits, processing unit choices
- PyTorch Conversion Workflow, tracing,
ct.convertandsave - Convert Models to ML Programs, the default model type, precision and the
.mlpackageformat - Licenses on the Hugging Face Hub and Model Cards, license metadata
- mlx-swift-lm and mlx-swift-examples, language models in Swift
- App Privacy Details, the definition of "collect" and on-device processing