ANTIGRAVITY LABJP
Articles/App Development
App Development/2026-03-26Intermediate

Edge AI with Antigravity — Building On-Device Inference Apps Using Core ML and TensorFlow Lite

Learn how to build on-device AI inference apps using Antigravity with Core ML and TensorFlow Lite. Covers model quantization, platform integration, and performance optimization.

edge-ai3core-ml3tensorflow-lite2on-device2antigravity432mobile-aimodel-quantization

Why On-Device AI Matters Now More Than Ever

Cloud-based AI APIs are convenient, but they come with inherent limitations: latency, connectivity costs, and privacy concerns. Edge AI — running inference directly on the device — addresses all of these challenges at their root.

In 2026, both Apple's Core ML and Google's TensorFlow Lite have matured into robust mobile inference engines. Combined with Antigravity's AI agent capabilities, you can streamline the entire workflow from model conversion and quantization to app integration and testing.

The Edge AI Development Pipeline

On-device AI development follows four main phases:

1. Model Preparation and Conversion

Start with a pre-trained model and convert it to a mobile-friendly format. This means taking PyTorch or TensorFlow models and converting them to Core ML (.mlmodel / .mlpackage) or TensorFlow Lite (.tflite) format.

2. Quantization and Optimization

Reduce model size to fit mobile resource constraints. INT8 quantization can shrink models by up to 75% while maintaining over 95% accuracy in most cases — a remarkably practical trade-off.

3. App Integration

Embed the converted model into your iOS or Android app. This includes implementing inference code, handling input/output format conversion, and connecting to the UI.

4. Testing and Benchmarking

Measure real-device latency, memory usage, and battery consumption to ensure production quality.

Antigravity's agents can assist with code generation, review, and test automation across all four phases.

Implementing Core ML for iOS On-Device Inference

Generating the Model Conversion Script with Antigravity

Ask Antigravity's agent to generate a script that converts a PyTorch model to Core ML format:

# convert_to_coreml.py
# Convert a PyTorch image classification model to Core ML format
import torch
import coremltools as ct
from torchvision.models import mobilenet_v3_small, MobileNet_V3_Small_Weights
 
# Load the pre-trained model
weights = MobileNet_V3_Small_Weights.DEFAULT
model = mobilenet_v3_small(weights=weights)
model.eval()
 
# Create a dummy input for tracing
dummy_input = torch.randn(1, 3, 224, 224)
traced_model = torch.jit.trace(model, dummy_input)
 
# Convert to Core ML with quantization options
mlmodel = ct.convert(
    traced_model,
    inputs=[ct.ImageType(name="image", shape=(1, 3, 224, 224))],
    convert_to="mlprogram",  # ML Program format (iOS 15+)
    compute_precision=ct.precision.FLOAT16,  # FP16 quantization halves the size
)
 
# Expected output:
# A .mlpackage file with metadata is generated
mlmodel.save("ImageClassifier.mlpackage")
print("✅ Core ML model conversion complete")
print(f"   Model size: ~{mlmodel.__sizeof__() / 1024 / 1024:.1f} MB")

By specifying compute_precision=ct.precision.FLOAT16, we reduce model size by approximately 50% while preserving accuracy.

Real-Time Inference in Swift

Integrate the converted model into your iOS app. You can use Antigravity's inline chat (⌘+I) to efficiently generate the Swift implementation:

// ImageClassifierService.swift
// Service for real-time image classification using Core ML
import CoreML
import Vision
 
class ImageClassifierService {
    private let model: VNCoreMLModel
 
    init() throws {
        // Load the Core ML model
        let config = MLModelConfiguration()
        config.computeUnits = .all  // Automatically selects Neural Engine + GPU + CPU
        let mlModel = try ImageClassifier(configuration: config).model
        self.model = try VNCoreMLModel(for: mlModel)
    }
 
    func classify(image: CGImage) async throws -> [(label: String, confidence: Float)] {
        return try await withCheckedThrowingContinuation { continuation in
            let request = VNCoreMLRequest(model: model) { request, error in
                if let error = error {
                    continuation.resume(throwing: error)
                    return
                }
                guard let results = request.results as? [VNClassificationObservation] else {
                    continuation.resume(returning: [])
                    return
                }
                // Return the top 5 classification results
                let topResults = results.prefix(5).map {
                    (label: $0.identifier, confidence: $0.confidence)
                }
                continuation.resume(returning: topResults)
            }
            // Prefer Neural Engine over CPU
            request.usesCPUOnly = false
 
            let handler = VNImageRequestHandler(cgImage: image)
            try? handler.perform([request])
        }
    }
}
 
// Expected output:
// [("golden_retriever", 0.92), ("labrador", 0.05), ("dog", 0.02), ...]

Setting computeUnits = .all allows the system to automatically leverage the Apple Neural Engine (ANE) on supported devices, dramatically improving inference speed.

Cross-Platform Support with TensorFlow Lite

INT8 Quantization for Model Compression

TensorFlow Lite supports post-training quantization (PTQ) that drastically reduces model size. Have Antigravity's agent generate the conversion script:

# quantize_tflite.py
# Convert a TensorFlow model to INT8 quantized TFLite format
import tensorflow as tf
import numpy as np
 
# Representative dataset generator for quantization calibration
def representative_dataset():
    """Provide representative data to maintain quantization accuracy"""
    for _ in range(100):
        # Use input data similar to actual use cases
        data = np.random.rand(1, 224, 224, 3).astype(np.float32)
        yield [data]
 
# Convert SavedModel to TFLite
converter = tf.lite.TFLiteConverter.from_saved_model("saved_model/")
converter.optimizations = [tf.lite.Optimize.DEFAULT]
converter.representative_dataset = representative_dataset
converter.target_spec.supported_ops = [tf.lite.OpsSet.TFLITE_BUILTINS_INT8]
converter.inference_input_type = tf.uint8
converter.inference_output_type = tf.uint8
 
tflite_model = converter.convert()
 
# Save the quantized model
with open("model_quantized.tflite", "wb") as f:
    f.write(tflite_model)
 
# Expected output:
# File size reduced to approximately 25% of the original
# Example: 16MB → 4MB (after INT8 quantization)
original_size = 16.0  # MB (example)
quantized_size = len(tflite_model) / 1024 / 1024
print(f"✅ Quantization complete")
print(f"   Original size: {original_size:.1f} MB")
print(f"   Quantized: {quantized_size:.1f} MB")
print(f"   Reduction: {(1 - quantized_size / original_size) * 100:.0f}%")

INT8 quantization can reduce model size by approximately 75% while maintaining over 95% inference accuracy — a significant win for mobile deployment.

Android Inference with Kotlin

Use Antigravity's Agent mode to generate Android inference code in one shot:

// EdgeAIClassifier.kt
// Image classification for Android using TensorFlow Lite
import android.content.Context
import android.graphics.Bitmap
import org.tensorflow.lite.Interpreter
import org.tensorflow.lite.gpu.GpuDelegate
import java.io.FileInputStream
import java.nio.ByteBuffer
import java.nio.ByteOrder
import java.nio.MappedByteBuffer
import java.nio.channels.FileChannel
 
class EdgeAIClassifier(private val context: Context) {
 
    private var interpreter: Interpreter? = null
    private var gpuDelegate: GpuDelegate? = null
 
    fun initialize() {
        // Enable GPU delegate for hardware acceleration
        gpuDelegate = GpuDelegate()
        val options = Interpreter.Options().apply {
            addDelegate(gpuDelegate!!)
            setNumThreads(4) // Fallback when GPU is unavailable
        }
        val modelBuffer = loadModelFile("model_quantized.tflite")
        interpreter = Interpreter(modelBuffer, options)
    }
 
    fun classify(bitmap: Bitmap): List<Pair<String, Float>> {
        val inputBuffer = preprocessImage(bitmap)
        val outputBuffer = Array(1) { FloatArray(1000) }
 
        interpreter?.run(inputBuffer, outputBuffer)
 
        // Return top 5 results as label-score pairs
        return outputBuffer[0]
            .mapIndexed { index, score -> Pair(labels[index], score) }
            .sortedByDescending { it.second }
            .take(5)
    }
 
    // Expected output:
    // [("golden_retriever", 0.91), ("labrador", 0.04), ...]
 
    private fun preprocessImage(bitmap: Bitmap): ByteBuffer {
        val buffer = ByteBuffer.allocateDirect(1 * 224 * 224 * 3)
        buffer.order(ByteOrder.nativeOrder())
        val resized = Bitmap.createScaledBitmap(bitmap, 224, 224, true)
        val pixels = IntArray(224 * 224)
        resized.getPixels(pixels, 0, 224, 0, 0, 224, 224)
        for (pixel in pixels) {
            buffer.put(((pixel shr 16) and 0xFF).toByte()) // R
            buffer.put(((pixel shr 8) and 0xFF).toByte())  // G
            buffer.put((pixel and 0xFF).toByte())            // B
        }
        return buffer
    }
 
    private fun loadModelFile(filename: String): MappedByteBuffer {
        val fd = context.assets.openFd(filename)
        val input = FileInputStream(fd.fileDescriptor)
        val channel = input.channel
        return channel.map(FileChannel.MapMode.READ_ONLY, fd.startOffset, fd.declaredLength)
    }
 
    fun release() {
        interpreter?.close()
        gpuDelegate?.close()
    }
 
    companion object {
        private val labels = listOf(/* ImageNet labels — 1000 entries */)
    }
}

The GpuDelegate enables hardware acceleration on supported devices, delivering 2–5x speed improvements over CPU-only execution.

Leveraging Antigravity Agents in Your Workflow

Step 1: Project Setup

Launch Antigravity and create a new project. Writing an AGENTS.md file with mobile AI development context improves agent accuracy:

<!-- AGENTS.md -->
# Edge AI Mobile App Project
 
## Context
- iOS: Swift + Core ML (targeting iOS 17+)
- Android: Kotlin + TensorFlow Lite (targeting API 26+)
- Model: MobileNetV3-based image classification
 
## Coding Standards
- Never skip error handling
- Always implement model release/cleanup to prevent memory leaks
- Include performance measurement logging in inference code

Step 2: Agent-Driven Code Generation

In Antigravity's Agent mode, simply ask "Create a Core ML inference service class" and the implementation shown above will be generated automatically. Follow up with "Create a TensorFlow Lite version with the same interface" for cross-platform coverage.

Step 3: Testing and Benchmarking

Ask Antigravity's agent to "generate unit tests and performance benchmarks for inference," and it will produce test code automatically:

// ImageClassifierTests.swift
// Benchmark tests for inference accuracy and latency
import XCTest
@testable import MyApp
 
class ImageClassifierTests: XCTestCase {
    var classifier: ImageClassifierService!
 
    override func setUpWithError() throws {
        classifier = try ImageClassifierService()
    }
 
    func testClassificationAccuracy() async throws {
        let testImage = loadTestImage("golden_retriever.jpg")
        let results = try await classifier.classify(image: testImage)
 
        XCTAssertFalse(results.isEmpty, "Classification results are empty")
        XCTAssertEqual(results[0].label, "golden_retriever")
        XCTAssertGreaterThan(results[0].confidence, 0.8)
    }
 
    func testInferenceLatency() async throws {
        let testImage = loadTestImage("sample.jpg")
 
        // Measure average latency over 10 runs
        let start = CFAbsoluteTimeGetCurrent()
        for _ in 0..<10 {
            _ = try await classifier.classify(image: testImage)
        }
        let elapsed = (CFAbsoluteTimeGetCurrent() - start) / 10
 
        // Expect under 20ms when using Neural Engine
        print("Average inference time: \(elapsed * 1000)ms")
        XCTAssertLessThan(elapsed, 0.1, "Inference time exceeds 100ms")
    }
 
    // Expected output:
    // Average inference time: 12.3ms (iPhone 15 Pro, Neural Engine)
}

Looking back

Edge AI is quickly becoming the standard for mobile app development. On-device inference with Core ML and TensorFlow Lite delivers three major benefits: reduced latency, enhanced privacy, and offline capability.

By leveraging Antigravity's AI agents, you can streamline model conversion scripts, inference code, and test generation — significantly reducing development time. Start by converting an existing model to Core ML or TFLite format and building a small prototype to see the results firsthand.

For more hands-on mobile development techniques, check out the Antigravity × Flutter Mobile Development Complete Guide and Antigravity × Xcode 26 / iOS 26 Development Guide.

If you'd like to dive deeper into the topics covered in this article,

Share

Thank You for Reading

Antigravity Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • Copy-paste ready implementation code
  • New advanced guides published daily
  • $5/mo or $10 for lifetime access
View Membership →

If you found this article helpful, a small tip ($1.50) would mean a lot to us. Your support helps keep this site ad-free and covers server and hosting costs.

Related Articles

App Dev2026-04-25
Gemma 4 × Antigravity — Complete Guide to On-Device AI for iOS and Android
A hands-on implementation guide for integrating Gemma 4 into both iOS (Core ML) and Android (TensorFlow Lite / AI Core) with Antigravity. Covers model conversion, quantization, battery management, and app store approval.
App Dev2026-07-13
The Gate That Stops Visual Damage Before You Hand Bulk Image Optimization to an Agent
When an agent bulk re-encoded a few hundred wallpaper assets, a handful came back with dulled color. Size-reduction alone cannot catch that. Here is how to design a gate that stops bad conversions before merge using three axes — SSIM, ΔE, and file size — with a checker that runs on Pillow and scikit-image.
App Dev2026-07-09
Deciding When to Stop a Staged Rollout, Before You Have To — Agents Watch, I Halt
Field notes on building a Google Play staged-rollout watcher with Antigravity. Crash rate as a ratio to baseline, delayed ANR evaluation, and an explicit insufficient_data verdict — with the halt action kept in human hands.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links
See all →