← Research

Running V-JEPA 2.1 on an iPhone

V-JEPA 2.1 encoder and predictor with 1.9 billion parameters

iPhone 15 Pro | Core ML | Local inference

The main result

We ran the complete V-JEPA 2.1 ViT-G encoder and predictor on an iPhone 15 Pro, with no server involved in inference. Together, these models contain about 1.9 billion parameters. With four-frame clips at 128 × 128 pixels, the loaded model stack took about 108 ms per fixed-input run. In a separate live camera test, the app produced about five updates per second for more than five minutes.

Three design choices made this deployment possible: four-bit lookup-table storage for the encoder weights, four encoder stages that stay loaded between calls, and a separate FP16 predictor. The model files occupy about 1.05 GB. Core ML runs the stages in sequence, without reloading them from storage for each update.

These measurements describe an interactive phone demonstration. The live test reached high thermal states, so sustained operation is the next target. We explain how the model was prepared for the phone, what compression changed, and which parts of the approach other engineers can reuse.

1. Why JEPA

We want to build an assistant that follows a person’s activity and prepares useful help for what comes next. It could bring up the next instruction during a task, or leave the interface unchanged when help is not needed. This goal led us to JEPA, short for Joint Embedding Predictive Architecture. Its encoder converts observed video into learned numerical features, called latent representations. Its predictor uses those features to estimate the representation of a hidden part of the video. When that hidden part comes later in time, we can study possible future states without generating the future video itself. [1, 2]

These features do not directly tell an interface what to display. We need an action head, a small model that learns to turn features into labels for human actions. A separate policy would then decide whether assistance is useful and what to show. Our phone demonstration already includes an action head. The next part we want to develop is the policy that connects these outputs to useful assistance, including when to leave the interface unchanged.

We chose to run the encoder and predictor on the phone. This keeps video processing local and removes the need for a network connection during inference. We first made the encoder run, then added the predictor and tested repeated updates from the camera. This gave us a working system for testing action heads. Longer operation on wearable devices will also require tests of battery use and heat.

Overview / 01

From activity to useful assistance

01 / Observe
Observed activityWhat is the person doing?
Activity stateWhat matters in the current context?
02 / Anticipate
Possible future stateWhat might happen next?
03 / Interface response
Would assistance help?Use the current and possible future state
Yes ↓
Adapt the interfaceShow guidance, information, or controls
No ↓
Remain unchangedDo not interrupt the user
Figure 1. From observed activity to an interface response. An adaptive interface uses the observed activity and a possible future state to decide whether assistance is useful. It can show relevant support or remain unchanged.

2. What runs on the phone

For each update, the app collects four recent camera frames into one clip. Each frame is resized to 128 × 128 pixels before the clip enters the encoder.

The encoder does not process the clip as one large image. It first divides it into tubelets: small image patches that cover the same location across two consecutive frames. Each tubelet is converted into a list of numbers called a token. The encoder processes these tokens together to learn relationships across the image and over time.

The encoder produces numerical features that describe the video. The predictor uses observed features to estimate features for a target part of the video. This target can be a later video segment. Both models run through Core ML, Apple’s software framework for running machine-learning models on the device.

The app displays the action head’s highest-scoring labels. This gives us a readable output to inspect as the camera view changes. Our next step is to connect these labels to a UI policy. That policy would decide whether to offer help and what the interface should show.

The system / 02

From video to predicted features.

V-JEPA 2.1 · Local encoder + predictor · Core ML

01
02
03
04

4 frames · 128 × 128 model input

On the phone
1234
Encoder4 stages · all 48 blocks
Observed features
PredictorEstimate the target in feature space
Predicted features
Not a video frameOutput shown as a diagram
Action head → action labelsFuture UI policy → useful assistance

Input frames: saved iPhone 15 Pro dog-clip test. Model path: simplified system diagram.

Figure 2. From video to predicted features. The model path is simplified; the output tiles are a diagram, not measured predictions. The sample frames come from the iPhone 15 Pro dog-clip test. A separate action head produces labels. The UI policy is future work.

3. How the model fits on the phone

The phone needs space both to store the models and to run them. Storage keeps the model files. Working memory, or RAM, holds data used while the models run. Model weights are the numbers learned during training. With FP16, each weight uses two bytes. Our encoder and predictor would need about 3.8 GB for weights alone. The models do not have all the phone’s RAM to themselves. iOS, the app, and the temporary results produced during inference also need memory. We compressed the encoder weights while keeping all 48 encoder blocks and the predictor.

We compressed the encoder weights with LUT4 palettization, shown in Figure 3a. Each group of weights shares a table of 16 values. Each compressed weight uses a four-bit index that selects an approximate weight value from this table. The predictor stays in FP16. Together, the model files occupy about 1.05 GB. This is file storage, not the total RAM needed to run the models. Temporary results, called activations, remain in floating point. LUT4 therefore describes how we store weights, not the precision of every calculation. [5]

Weight compression / 03a

How palettization stores weights

Original weights

FP16 · 16 bits per weight

−0.82−0.780.180.741.410.220.761.39

Nearby weights share one table value.

Compress

Stored indices

LUT4 · 4 bits per index

005101551015

Shared table

4 of 16 entries shown

IndexWeight value0−0.8050.20100.75151.40
Look up

Recovered weights

Values from the shared table

−0.80−0.800.200.751.400.200.751.40

The recovered values are approximations.

Store indices + shared tablesWeight storage ≠ calculation precision

Illustrative values · Small excerpt from one group · Not measured model weights · Apple [5]

Figure 3a. How palettization stores weights. The example shows four of 16 table entries for one group, not measured model weights. Storage includes both indices and shared tables. The diagram explains how the compressed weights are stored and recovered. It does not show the exact steps the iPhone chip uses during inference. [5]

Compressing the encoder provided enough storage reduction for the phone demonstration. The smaller predictor occupies about 120 MB in FP16 and fits alongside it. We kept activations in floating point because this was faster in our matched phone test. With the LUT4 weights and FP16 predictor unchanged, adding INT8 activation quantization increased total model time from about 115 ms to 316 ms, as shown in Figure 3c. The demonstration therefore keeps mainly FP16 activations, with selected attention operations in FP32. Further predictor compression remains a separate optimization opportunity.

A small model file does not guarantee that the phone can load it. Core ML also needs working memory to prepare the model for execution. When we packaged the complete encoder as one file, iOS stopped the app during loading, before it could process a clip. This was consistent with memory pressure during preparation, although we did not confirm the exact cause. We therefore divided the encoder into four smaller model files, which loaded successfully. The boundaries follow four points where the original encoder provides features to the predictor, so all 48 blocks remain in use. The app loads these stages and the predictor at startup and keeps them available. Each new clip then passes through the stages in order, without loading the model files again.

Memory + compute / 03b

V-JEPA on the iPhone

Core MLModels stay loaded
4 frames
Encoder · LUT4
1234
Saved features from all four stages
PredictorFP16
Predicted features

iPhone 15 Pro

Flash storageModel files
≈1.05 GB
Load at startup
Shared RAMModel dataTemporary resultsRuntime + app + iOS
Access ↔
A17 ProAllowed model processors
CPUNeural Engine
GPU · Not selectedOn-chip caches / local memory
File size ≠ RAM useConceptual view · Not a processor-use measurement
Figure 3b. How V-JEPA runs inside the iPhone. The model steps sit above a view of storage, shared RAM and processors. All five model objects stay loaded between updates. The app allows CPU and Neural Engine execution; the links do not show measured processor use. Model file size is not runtime RAM use. [8–10]
Activation precision / 03c

INT8 activations took longer in this test

Same LUT4 weights · Same FP16 predictor · Same input

Lower is better

iPhone 15 Pro · Core ML · 4 frames at 128 × 128 · Median after startup

*Mainly FP16; selected attention operations use FP32. Loading, camera capture, and UI time are excluded.

Figure 3c. INT8 activations increased model run time in the matched iPhone test. Model loading is excluded.

Using fewer bits does not guarantee a faster model. Converting values or changing how operations run can add extra work. In our test, INT8 slowed the encoder, while the predictor took the same time. Profiling is the next step to find out why.

4. Preparing the model for local inference

The released model uses PyTorch, the framework used to build and train it. Our iPhone app uses Core ML to run the model, so we needed to convert it. We first traced each encoder stage and the predictor with example inputs to record their calculations. We then used Core ML Tools to convert these calculations and the learned weights into model packages for the app. This step did not retrain the model. We fixed the input clip size at four frames, each 128 × 128 pixels. The video content can change; only the number and size of the frames stay fixed. This gives the conversion tools a known workload to prepare for execution. [3, 4]

Before measuring speed, we checked the converted model’s outputs against the original PyTorch model on the same two video clips. We first checked for invalid numerical values, such as infinities. We then used cosine similarity to compare the output features. This measure compares the direction of two feature vectors; a value near one means their directions are close. It helps us measure changes caused by conversion and compression. Feature similarity does not tell us whether an action label is correct.

For live use, we prioritize recent activity over processing every camera frame. The app runs one clip at a time while it continues to collect new frames. When that run finishes, it starts the next clip from the latest available frames. It does not keep a growing list of clips waiting for processing. This prevents the results from falling further behind the camera view when frames arrive faster than the model can process them.

Model deployment / 04

From PyTorch to the iPhone

V-JEPA 2.1 · Encoder + predictor · Core ML

  1. 01 / Prepare

    PyTorch model

    01
    02
    03
    04

    4 frames · 128 × 128 model input

    Export a fixed graph

    4 encoder stages + predictor

  2. 02 / Convert + compress

    Core ML

    1234
    P

    Encoder + predictor · .mlpackage

    LUT4 encoder · FP16 predictor

    Activations stay in floating point

  3. 03 / Compile + run
    Core ML
    1234
    Predictor
    Local inference

    .mlmodelc · Phone diagram

    Load once. Run locally.

    All five models stay loaded

Output checkCompare PyTorch and Core ML features on the same clip.

Input frames: saved dog-clip test. The phone is a diagram, not an app screenshot.

Figure 4. From PyTorch to local Core ML inference. Fixed-input encoder stages and the predictor are converted into model packages, then compiled for the app. Encoder weights use LUT4; activations stay in floating point. The five models stay loaded between updates. Frames show an example input; the phone is a diagram.

5. Measured phone performance

We measured the complete encoder and predictor on an iPhone 15 Pro through Core ML. Each input contained four frames at 128 × 128 pixels. The encoder used LUT4 weight storage, and the predictor used FP16.

5.1. Model speed and live updates

We measured speed in two ways. First, we ran the loaded encoder and predictor ten times with the same prepared input. The median run time was about 108 ms. This measures model execution, without camera capture or screen updates. We then tested the complete app with the live camera. It completed 1,605 updates in about 5.3 minutes, averaging five updates per second. This second measurement includes the work needed to collect frames, prepare clips, run the models, and update the screen.

Measured phone performance
MeasurementResult
Initial model preparationAbout 49 seconds
Loaded encoder and predictor, fixed inputAbout 108 ms per run
Complete live camera update rateAbout 5 updates per second
Live test durationAbout 5.3 minutes

The phone was already warm from earlier tests when the live run started. During the run, iOS reported serious and critical thermal states. [6] The app continued to produce results without a logged error or crash. The five-updates-per-second result therefore describes operation under these test conditions. Our next step is to repeat the test from a cool start and track update speed alongside thermal state over a longer period. This will help us choose an update rate for longer use.

Before processing clips, the app must load and prepare the four encoder stages and the predictor. This took about 49 seconds in the recorded startup test. The models then stayed loaded, so subsequent runs did not repeat this preparation. The 108 ms result measures execution after loading, not the wait before the first result. Reducing this startup delay is another target for future work.

Phone performance / 05

Local inference on iPhone 15 Pro

Core ML · 4 frames at 128 × 128 · LUT4 encoder + FP16 predictor

108 msLoaded model run

Fixed input · median of 10 runs

≈5 /sLive camera updates

Average across the live test

5.3 minLive test duration

1,605 recorded updates

Completed live updates

Completed live updatesThe measured curve rises to 1,605 completed updates in about 5.3 minutes. This curve is reproduced from Figure 5 of the supplied report.

Elapsed time (minutes)

Separate startup measurement: about 49 seconds before repeated runs.

Live test reached serious and critical thermal states. Longer low-heat operation is future work.

Figure 5. Model execution and live camera performance are separate measurements. The curve shows completed updates from the live test log. The 108 ms result measures the loaded encoder and predictor with fixed input; it is not the live camera update time. Startup was measured separately.

5.2. Comparing model outputs

For this comparison, we used the Core ML version with LUT4 encoder weights and an FP16 predictor. On the two test clips, its observed-activity features stayed closer to the original PyTorch outputs than its predicted-future features did. This result comes from the centred cosine comparison with the original PyTorch outputs. It shows that the two types of output changed by different amounts in this test. It does not tell us how often an action label would be correct. To guide further compression, we will extend the comparison to more clips and measure action recognition accuracy alongside feature similarity.

Figure 6 shows a separate encoder test on an iPhone 15 Pro using a dog video. To display the model’s features, we use principal component analysis (PCA). This reduces each set of feature values to three values, which we display as red, green, and blue. We calculate this mapping from the reference model’s features, then use the same mapping and color scale for the phone outputs. This makes the visible patterns directly comparable. The colors show a simplified view of the features, not reconstructed video or an image of the future. [1]

On-device vision / 06

Same clip. Compressed model.

V-JEPA 2.1 · Encoder outputs · iPhone 15 Pro · Core ML

01
02
03
04

4 frames · 128 × 128 model input

Reference

FP32 weights

On iPhone

LUT4 weights · floating-point activations

Shared PCA colors show features, not reconstructed video.0.90 cosine similarity
Figure 6. Reference and phone encoder outputs for one dog clip. This separate iPhone 15 Pro test compares the dense FP32 reference with Core ML LUT4-A16. Both maps use the same reference-fitted PCA projection and color scale; each pair shows two temporal feature groups. The 0.90 value is uncentred cosine similarity across encoder features, not action accuracy or the two-clip centred comparison above.

6. From model features to useful assistance

To turn the model’s numerical features into readable action labels, we train a small model called an action head. For the four-frame phone demonstration, we use Something-Something V2, a video dataset with 174 action categories. Each training example pairs video features with an action label. The head learns to score these categories, and the app displays the labels with the highest scores. During this training, the encoder’s learned weights do not change. We can therefore train the action head without retraining the large encoder. [7]

6.1. From action labels to interface responses

Recognizing an activity is only the first step toward useful assistance. If someone is repairing a bicycle tire, the interface could offer instructions for the next step. The next challenge is learning when that help is useful and when the interface should stay quiet.

We did not train a UI policy: the component that decides what the interface should show and when. Recognizing an action does not tell us which response would help. Two people assembling the same object may need different guidance, and neither may want an interruption. Training this component would need examples that pair a person’s activity with a useful response, including cases where the interface should do nothing. We would then test those responses with users. The phone demo produces action labels; learning how to use them to offer help remains future work.

Assistance / 07

From action labels to useful assistance

The action head produces labels. A future UI policy would choose a response.

V-JEPAfeatures
Action headSomething-Something V2 [7]
174 action labels
Action labels+ scores
Proposed · Not trained
Future training examplesActivity + useful response
UI policy
Offer helpor stay unchanged

Local video frame

Working on a bicycle tire.

Possible UI response

Need the next step?
Open instructionsDismiss

An optional card, not an automatic interruption.

Example UI · not a prediction

Frame: Ego-Exo4D, cmu_bike01_4, 00:22. UI card: design example, not a phone prediction.

Figure 7. From action labels to a possible interface response. The action head produces labels. A future UI policy would decide whether to offer help or leave the interface unchanged. The bicycle-repair frame is from Ego-Exo4D. [11] The UI card is a design example, not an output from the phone app.

7. Toward sustained wearable assistance

The phone demo gives us a starting point. The next question is whether this system can stay useful throughout the day. On a wearable device, speed is only part of the problem: battery life and heat also matter. We may not need to run the model as often when little is changing. For example, someone sitting at a desk may need fewer updates than someone moving through an assembly task. Longer tests would help us find an update rate that keeps the system responsive without doing unnecessary work.

The model must also provide useful information at that operating rate. Broader comparisons with the reference model and action-level tests can guide further compression. A comparison with the original V-JEPA results requires matched inputs and evaluation methods. [1] For future-action prediction, the next tests should measure whether predicted features improve decisions about what happens next. User-reviewed examples can then connect those decisions to useful interface responses.

For someone wearing smart glasses, the useful result is not an action label. It is getting the right help at the right time: the next assembly instruction, a relevant diagram, or information they would otherwise need to search for. Just as important is knowing when to stay quiet. Our phone demo gives us a way to develop and test these ideas with local video processing. The longer-term goal is an assistant that helps people continue their task, while leaving them in control of when and how it responds.

References

[1] L. Mur-Labadia et al. (2026). V-JEPA 2.1: Unlocking Dense Features in Video Self-Supervised Learning. arXiv:2603.14482v3. Model background, hierarchical training, evaluation protocols, and PCA visualization. V-JEPA 2.1 paper

[2] M. Assran et al. (2025). V-JEPA 2: Self-Supervised Video Models Enable Understanding, Prediction and Planning. arXiv:2506.09985. Latent prediction and the separate action-conditioned model. V-JEPA 2 paper

[3] Apple. PyTorch Conversion Workflow. Guide to Core ML Tools. Graph capture and conversion. Apple conversion guide

[4] Apple. Model Prediction. Guide to Core ML Tools, section Using Compiled Python Models for Prediction. Package compilation and device specialization. Apple compilation guide

[5] Apple. Palettization Overview. Guide to Core ML Tools. Lookup-table weight storage and grouped-channel compression. Apple palettization guide

[6] Apple. ProcessInfo.ThermalState.serious. Foundation documentation. Thermal limits and reduced system performance. Apple thermal-state documentation

[7] Qualcomm Technologies. Something-Something v. 2 Dataset. Official dataset description and 174 action labels. Something-Something V2 dataset

[8] Apple. iPhone 15 Pro specifications. Apple hardware

[9] Apple. Choosing a resource storage mode for Apple GPUs. shared memory

[10] Apple. MLComputeUnits.cpuAndNeuralEngine. Core ML settings

[11] Ego-Exo4D. Official dataset website. Source of the bicycle-repair frame in Figure 7 (cmu_bike01_4, 00:22). Ego-Exo4D dataset