Skip to main content
Quand vous développez en Swift, la première question n’est pas “quel modèle est le meilleur ?”. La vraie question est : où vit le modèle et qui le sert ? En pratique, vous avez trois approches utiles.

1. Foundation Models : le choix le plus simple côté app

Si le modèle système Apple suffit à votre cas d’usage, commencez ici. C’est l’option la plus naturelle pour une app Swift moderne :
  • API Swift native
  • sortie structurée avec @Generable
  • streaming
  • tools
  • modèle fourni par le système
import FoundationModels

let session = LanguageModelSession(
    instructions: "You are a concise assistant for Swift developers."
)

let response = try await session.respond(
    to: "Explain when to use structured output."
)

print(response.content)
Cette approche est idéale si vous voulez ajouter de l’IA dans une app Apple sans gérer vous-même les poids d’un modèle.

2. MLX Swift : pour charger un modèle open weight dans l’app

Si vous avez besoin d’un modèle précis issu de mlx-community ou d’un modèle fine-tuné par vos soins, regardez mlx-swift et les exemples officiels.

Ajouter le package

dependencies: [
    .package(
        url: "https://github.com/ml-explore/mlx-swift",
        branch: "main"
    )
]

Exemple de chargement

import MLXLMCommon
import MLXLLM

let configuration = ModelConfiguration(
    id: "mlx-community/Llama-3.2-3B-Instruct-4bit"
)

let container = try await LLMModelFactory.shared
    .loadContainer(configuration: configuration)
Ensuite, vous encapsulez ce conteneur dans un view model SwiftUI pour gérer :
  • le téléchargement
  • l’état de chargement
  • le streaming
  • les erreurs mémoire
Cette voie vous donne plus de contrôle, mais elle vous demande aussi plus de travail qu’avec Foundation Models. Vous gérez le modèle, son cycle de vie et souvent sa distribution.

3. Un serveur local consommé depuis Swift

Si vous ne voulez pas embarquer le modèle dans l’app, servez-le à part puis appelez-le en HTTP depuis Swift. Cette stratégie fonctionne bien avec :
  • mlx_lm.server
  • Ollama
  • llama.cpp en mode serveur

Exemple Swift avec URLSession

import Foundation

struct ChatRequest: Encodable {
    let model: String
    let messages: [[String: String]]
}

struct ChatResponse: Decodable {
    struct Choice: Decodable {
        struct Message: Decodable {
            let content: String
        }

        let message: Message
    }

    let choices: [Choice]
}

func sendPrompt() async throws -> String {
    let url = URL(string: "http://localhost:8080/v1/chat/completions")!
    var request = URLRequest(url: url)
    request.httpMethod = "POST"
    request.setValue("application/json", forHTTPHeaderField: "Content-Type")

    let body = ChatRequest(
        model: "mlx-community/Llama-3.2-3B-Instruct-4bit",
        messages: [
            ["role": "user", "content": "Explain MLX in simple terms."]
        ]
    )

    request.httpBody = try JSONEncoder().encode(body)

    let (data, _) = try await URLSession.shared.data(for: request)
    let response = try JSONDecoder().decode(ChatResponse.self, from: data)
    return response.choices.first?.message.content ?? ""
}
Cette approche sépare bien l’app Swift du backend modèle. Elle est utile si vous voulez changer de backend sans refaire l’UI.

Où se place Core ML ?

Core ML reste important dans l’écosystème Apple, mais pour un développeur moyen qui découvre les LLMs, ce n’est pas toujours le point d’entrée le plus simple. Pour un LLM complet, Core ML implique souvent plus de travail :
  • conversion du modèle
  • gestion du tokenizer
  • boucle de génération
  • packaging du modèle
Si votre besoin est surtout du texte génératif :
  • commencez par Foundation Models pour le modèle système Apple
  • ou par MLX / serveur local pour un modèle open weight
Passez à Core ML lorsque vous avez une contrainte précise de packaging ou de déploiement.

Trois axes pour décider

Quand vous hésitez entre ces approches, comparez-les sur trois axes très concrets :
AxeFoundation ModelsMLX SwiftServeur local
Gestion du modèleApple fournit et prépare le modèle systèmeVous chargez, distribuez et maintenez le modèle dans l’appVous maintenez un backend local séparé de l’app
Contrôle des poidsTrès faibleTotalTotal, mais côté backend
Coût d’intégrationLe plus faible côté appLe plus élevé côté appMoyen : UI simple, backend à opérer
Pour un développeur Swift de niveau intermédiaire, ce tableau évite une confusion fréquente : la solution la plus puissante n’est pas toujours la plus rentable à intégrer.

Quelle option choisir ?

BesoinOption recommandée
Ajouter rapidement une fonctionnalité IA dans une app SwiftFoundation Models
Utiliser un modèle open weight précis dans l’écosystème AppleMLX Swift
Garder l’app légère et interroger un backend localServeur HTTP local