SPB Git

spb/zyquo-mlx Public MIT

The local MLX foundry for your Mac — run, fine-tune, quantize, and ship models. Nothing leaves your machine.

Swift 93.4% Python 3.8% Makefile 2.2% Shell 0.5%
2.5 KB · 76 lines swift
Raw Blame History
1//2//  ModelTypeAdapters.swift3//  Zyquo MLX4//5//  Author: Simon-Pierre Boucher6//  Mail: contact@spboucher.ai7//89import Foundation10import MLX11import MLXEmbedders12import MLXHuggingFace13import MLXLLM14import MLXLMCommon15import MLXVLM16import Tokenizers  // required by the #huggingFaceTokenizerLoader macro expansion1718/// A loaded model held by the engine, dispatched by `ModelType`.19///20/// LLM and VLM share `ModelContainer` (both come from `ModelFactory`21/// implementations); embeddings use `EmbedderModelContainer`. Speech and22/// image generation run through the Python bridge (Phase 3+) and never hold23/// in-process state here.24enum LoadedModelAdapter {25    case language(ModelContainer)   // .llm and .vlm26    case embedder(EmbedderModelContainer)27}2829/// Events streamed to callers during generation.30enum InferenceEvent: Sendable {31    case chunk(String)32    case finished(InferenceStats)33}3435enum InferenceEngineError: LocalizedError {36    case unsupportedType(ModelType)37    case noModelLoaded38    case wrongModelKind(expected: String)3940    var errorDescription: String? {41        switch self {42        case .unsupportedType(let type):43            "\(type.displayName) models run through the Python pipelines — not the in-process engine."44        case .noModelLoaded:45            "No model is loaded."46        case .wrongModelKind(let expected):47            "The loaded model is not \(expected)."48        }49    }50}5152enum ModelTypeAdapters {5354    /// Load a local model directory into the right container for its type.55    /// Tokenizers come from swift-transformers via the MLXHuggingFace macro56    /// (docs/MLX-RESEARCH.md §4.1/§4.4).57    static func load(model: LocalModel) async throws -> LoadedModelAdapter {58        switch model.type {59        case .llm:60            let container = try await LLMModelFactory.shared.loadContainer(61                from: model.directory, using: #huggingFaceTokenizerLoader())62            return .language(container)63        case .vlm:64            let container = try await VLMModelFactory.shared.loadContainer(65                from: model.directory, using: #huggingFaceTokenizerLoader())66            return .language(container)67        case .embedding:68            let container = try await EmbedderModelFactory.shared.loadContainer(69                from: model.directory, using: #huggingFaceTokenizerLoader())70            return .embedder(container)71        case .speech, .imageGeneration:72            throw InferenceEngineError.unsupportedType(model.type)73        }74    }75}76