From 97d9c912d029e10c77155d33e164af2aa6175df2 Mon Sep 17 00:00:00 2001 From: David Koski Date: Wed, 17 Dec 2025 13:59:52 -0800 Subject: [PATCH 1/2] add a minimal LLM chat example - LLMEval has more of a showcase of features and runtime statistics - this provides the minimum required to load a model and interact with it - also cleans up the xcodeproj (see #451) - removes VLMEval (redundant and wasn't maintained) --- .../AccentColor.colorset/Contents.json | 0 .../AppIcon.appiconset/Contents.json | 85 ++ .../Assets.xcassets/Contents.json | 0 Applications/LLMBasic/ChatModel.swift | 108 ++ Applications/LLMBasic/ContentView.swift | 82 ++ .../LLMBasic.entitlements} | 8 - Applications/LLMBasic/LLMBasicApp.swift | 22 + Applications/LLMBasic/README.md | 23 + Applications/LLMEval/README.md | 16 +- Applications/LLMEval/Views/ContentView.swift | 1 - .../AppIcon.appiconset/Contents.json | 35 - Applications/VLMEval/ContentView.swift | 486 --------- .../Preview Assets.xcassets/Contents.json | 6 - Applications/VLMEval/README.md | 43 - Applications/VLMEval/VLMEvalApp.swift | 13 - Package.swift | 1 - README.md | 11 +- mlx-swift-examples.xcodeproj/project.pbxproj | 986 ++++++++---------- .../xcshareddata/swiftpm/Package.resolved | 23 +- .../{VLMEval.xcscheme => LLMBasic.xcscheme} | 20 +- .../xcschemes/MLXChatExample.xcscheme | 78 ++ .../xcschemes/image-tool.xcscheme | 79 ++ 22 files changed, 915 insertions(+), 1211 deletions(-) rename Applications/{VLMEval => LLMBasic}/Assets.xcassets/AccentColor.colorset/Contents.json (100%) create mode 100644 Applications/LLMBasic/Assets.xcassets/AppIcon.appiconset/Contents.json rename Applications/{VLMEval => LLMBasic}/Assets.xcassets/Contents.json (100%) create mode 100644 Applications/LLMBasic/ChatModel.swift create mode 100644 Applications/LLMBasic/ContentView.swift rename Applications/{VLMEval/VLMEval.entitlements => LLMBasic/LLMBasic.entitlements} (53%) create mode 100644 Applications/LLMBasic/LLMBasicApp.swift create mode 100644 Applications/LLMBasic/README.md delete mode 100644 Applications/VLMEval/Assets.xcassets/AppIcon.appiconset/Contents.json delete mode 100644 Applications/VLMEval/ContentView.swift delete mode 100644 Applications/VLMEval/Preview Content/Preview Assets.xcassets/Contents.json delete mode 100644 Applications/VLMEval/README.md delete mode 100644 Applications/VLMEval/VLMEvalApp.swift rename mlx-swift-examples.xcodeproj/xcshareddata/xcschemes/{VLMEval.xcscheme => LLMBasic.xcscheme} (83%) create mode 100644 mlx-swift-examples.xcodeproj/xcshareddata/xcschemes/MLXChatExample.xcscheme create mode 100644 mlx-swift-examples.xcodeproj/xcshareddata/xcschemes/image-tool.xcscheme diff --git a/Applications/VLMEval/Assets.xcassets/AccentColor.colorset/Contents.json b/Applications/LLMBasic/Assets.xcassets/AccentColor.colorset/Contents.json similarity index 100% rename from Applications/VLMEval/Assets.xcassets/AccentColor.colorset/Contents.json rename to Applications/LLMBasic/Assets.xcassets/AccentColor.colorset/Contents.json diff --git a/Applications/LLMBasic/Assets.xcassets/AppIcon.appiconset/Contents.json b/Applications/LLMBasic/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 00000000..ffdfe150 --- /dev/null +++ b/Applications/LLMBasic/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,85 @@ +{ + "images" : [ + { + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "tinted" + } + ], + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + }, + { + "idiom" : "mac", + "scale" : "1x", + "size" : "16x16" + }, + { + "idiom" : "mac", + "scale" : "2x", + "size" : "16x16" + }, + { + "idiom" : "mac", + "scale" : "1x", + "size" : "32x32" + }, + { + "idiom" : "mac", + "scale" : "2x", + "size" : "32x32" + }, + { + "idiom" : "mac", + "scale" : "1x", + "size" : "128x128" + }, + { + "idiom" : "mac", + "scale" : "2x", + "size" : "128x128" + }, + { + "idiom" : "mac", + "scale" : "1x", + "size" : "256x256" + }, + { + "idiom" : "mac", + "scale" : "2x", + "size" : "256x256" + }, + { + "idiom" : "mac", + "scale" : "1x", + "size" : "512x512" + }, + { + "idiom" : "mac", + "scale" : "2x", + "size" : "512x512" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Applications/VLMEval/Assets.xcassets/Contents.json b/Applications/LLMBasic/Assets.xcassets/Contents.json similarity index 100% rename from Applications/VLMEval/Assets.xcassets/Contents.json rename to Applications/LLMBasic/Assets.xcassets/Contents.json diff --git a/Applications/LLMBasic/ChatModel.swift b/Applications/LLMBasic/ChatModel.swift new file mode 100644 index 00000000..5c97466a --- /dev/null +++ b/Applications/LLMBasic/ChatModel.swift @@ -0,0 +1,108 @@ +// Copyright © 2025 Apple Inc. + +import SwiftUI +import MLXLMCommon +import MLXLLM + +/// which model to load +private let modelConfiguration = LLMRegistry.gemma3_1B_qat_4bit + +/// instructions for the model (the system prompt) +private let instructions = + """ + You are a friendly and helpful chatbot. + """ + +/// parameters controlling generation +private let generateParameters = GenerateParameters(temperature: 0.5) + +/// Downloads and loads the weights for the model -- we have one of these in the process +@MainActor @Observable public class ModelLoader { + + enum State { + case idle + case loading(Task) + case loaded(ModelContainer) + } + + public var progress = 0.0 + public var isLoaded: Bool { + switch state { + case .idle, .loading: false + case .loaded: true + } + } + + private var state = State.idle + + public func model() async throws -> ModelContainer { + switch self.state { + case .idle: + let task = Task { + // download and report progress + try await loadModelContainer(configuration: modelConfiguration) { value in + Task { @MainActor in + self.progress = value.fractionCompleted + } + } + } + self.state = .loading(task) + let model = try await task.value + + self.state = .loaded(model) + return model + + case .loading(let task): + return try await task.value + + case .loaded(let model): + return model + } + } +} + +/// View model for the ChatSession +@MainActor @Observable public class ChatModel { + + private let session: ChatSession + + /// back and forth conversation between the user and LLM + public var messages = [Chat.Message]() + + private var task: Task? + public var isBusy: Bool { + task != nil + } + + public init(model: ModelContainer) { + self.session = ChatSession( + model, + instructions: instructions, + generateParameters: generateParameters) + } + + public func cancel() { + task?.cancel() + } + + public func respond(_ message: String) { + guard task == nil else { return } + + self.messages.append(.init(role: .user, content: message)) + self.messages.append(.init(role: .assistant, content: "...")) + let lastIndex = self.messages.count - 1 + + self.task = Task { + var first = true + for try await item in session.streamResponse(to: message) { + if first { + self.messages[lastIndex].content = item + first = false + } else { + self.messages[lastIndex].content += item + } + } + self.task = nil + } + } +} diff --git a/Applications/LLMBasic/ContentView.swift b/Applications/LLMBasic/ContentView.swift new file mode 100644 index 00000000..e5a51755 --- /dev/null +++ b/Applications/LLMBasic/ContentView.swift @@ -0,0 +1,82 @@ +// Copyright © 2025 Apple Inc. + +import SwiftUI +import MLXLMCommon + +struct ContentView: View { + + /// provided by the application + let loader: ModelLoader + + /// once loaded this will hold the chat session + @State var session: ChatModel? + @State var error: String? + + /// prompt for the LLM (text field) + @State var prompt = "" + + @FocusState var promptFocused + + var body: some View { + VStack { + if let error { + Text("Error: \(error)") + + } else if !loader.isLoaded { + ProgressView("Loading", value: loader.progress, total: 1) + + } else if let session { + // show the chat messages + ScrollView(.vertical) { + ForEach(session.messages.enumerated(), id: \.offset) { _, message in + let bold = message.role == .user + + HStack { + Text(message.content) + .bold(bold) + Spacer() + } + .padding(.bottom, 4) + } + + Spacer() + + if session.isBusy { + // a stop button -- cmd-. to interrupt + HStack { + Button("Stop", action: { session.cancel() }) + .keyboardShortcut(".") + Spacer() + } + } else { + // message from the user -> LLM + TextField("Prompt", text: $prompt) + .onSubmit(respond) + .focused($promptFocused) + .onAppear { + promptFocused = true + } + } + } + .defaultScrollAnchor(.bottom) + } + } + .padding() + .task { + do { + let model = try await loader.model() + self.session = ChatModel(model: model) + } catch { + self.error = error.localizedDescription + } + } + .onDisappear { + self.session?.cancel() + } + } + + private func respond() { + session?.respond(prompt) + prompt = "" + } +} diff --git a/Applications/VLMEval/VLMEval.entitlements b/Applications/LLMBasic/LLMBasic.entitlements similarity index 53% rename from Applications/VLMEval/VLMEval.entitlements rename to Applications/LLMBasic/LLMBasic.entitlements index 0ec64e4f..99f47167 100644 --- a/Applications/VLMEval/VLMEval.entitlements +++ b/Applications/LLMBasic/LLMBasic.entitlements @@ -4,13 +4,5 @@ com.apple.developer.kernel.increased-memory-limit - com.apple.security.app-sandbox - - com.apple.security.device.usb - - com.apple.security.files.user-selected.read-only - - com.apple.security.network.client - diff --git a/Applications/LLMBasic/LLMBasicApp.swift b/Applications/LLMBasic/LLMBasicApp.swift new file mode 100644 index 00000000..a514eec0 --- /dev/null +++ b/Applications/LLMBasic/LLMBasicApp.swift @@ -0,0 +1,22 @@ +// Copyright © 2025 Apple Inc. + +import SwiftUI +import MLXLMCommon +import MLXLLM +import MLX + +@main +struct LLMBasicApp: App { + + init() { + MLX.GPU.set(cacheLimit: 20 * 1024 * 1024) + } + + @State var loader = ModelLoader() + + var body: some Scene { + WindowGroup { + ContentView(loader: loader) + } + } +} diff --git a/Applications/LLMBasic/README.md b/Applications/LLMBasic/README.md new file mode 100644 index 00000000..a5e11586 --- /dev/null +++ b/Applications/LLMBasic/README.md @@ -0,0 +1,23 @@ +# LLMBasic + +A minimal example of: + +- loading a model, including downloading weights +- setting up a ChatSession +- a simple UI for a back and forth session with the model + +The `ChatModel` has a few parameters at the top if you want to try a different model or +system prompt. + +The goal of this example is to be a **minimal** application that loads and interacts with +an LLM. + +See `LLMEval` and `MLXChatExample` for more full featured applications. + +As always, you must set the Team on the LLMBasic target. + +Some notes about the setup: + +- this downloads models from hugging face so LLMBasic -> Signing & Capabilities has the "Outgoing Connections (Client)" set in the App Sandbox +- LLM models are large so this uses the Increased Memory Limit entitlement on iOS to allow ... increased memory limits for devices that have more memory +- `MLX.GPU.set(cacheLimit: 20 * 1024 * 1024)` is used to limit the buffer cache size diff --git a/Applications/LLMEval/README.md b/Applications/LLMEval/README.md index c7867503..2aab1b8b 100644 --- a/Applications/LLMEval/README.md +++ b/Applications/LLMEval/README.md @@ -14,6 +14,9 @@ Some notes about the setup: - LLM models are large so this uses the Increased Memory Limit entitlement on iOS to allow ... increased memory limits for devices that have more memory - `MLX.GPU.set(cacheLimit: 20 * 1024 * 1024)` is used to limit the buffer cache size +`MLXChatExample` is a more full featured multi-turn chat example that supports VLMs. +`LLMBasic` is a **minimal** LLM chat example. + ### Trying Different Models The example app uses an 8 billion parameter quantized Qwen3 model by default, see [LLMEvaluator.swift](ViewModels/LLMEvaluator.swift#L52): @@ -33,19 +36,6 @@ For example: var modelConfiguration = LLMRegistry.phi4bit ``` -### Troubleshooting - -If the program crashes with a very deep stack trace, you may need to build -in Release configuration. This seems to depend on the size of the model. - -There are a couple options: - -- Build Release -- Force the model evaluation to run on the main thread, e.g. using @MainActor -- Build `Cmlx` with optimizations by modifying `mlx/Package.swift` and adding `.unsafeOptions(["-O3"]),` around line 87 - -See discussion here: https://github.com/ml-explore/mlx-swift-examples/issues/3 - ### Performance Different models have difference performance characteristics. For example Gemma 2B may outperform Phi-2 in terms of tokens / second. diff --git a/Applications/LLMEval/Views/ContentView.swift b/Applications/LLMEval/Views/ContentView.swift index 76a397f7..e3372f2e 100644 --- a/Applications/LLMEval/Views/ContentView.swift +++ b/Applications/LLMEval/Views/ContentView.swift @@ -1,6 +1,5 @@ // Copyright © 2025 Apple Inc. -import AsyncAlgorithms import MLX import MLXLLM import MLXLMCommon diff --git a/Applications/VLMEval/Assets.xcassets/AppIcon.appiconset/Contents.json b/Applications/VLMEval/Assets.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index 23058801..00000000 --- a/Applications/VLMEval/Assets.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,35 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "platform" : "ios", - "size" : "1024x1024" - }, - { - "appearances" : [ - { - "appearance" : "luminosity", - "value" : "dark" - } - ], - "idiom" : "universal", - "platform" : "ios", - "size" : "1024x1024" - }, - { - "appearances" : [ - { - "appearance" : "luminosity", - "value" : "tinted" - } - ], - "idiom" : "universal", - "platform" : "ios", - "size" : "1024x1024" - } - ], - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/Applications/VLMEval/ContentView.swift b/Applications/VLMEval/ContentView.swift deleted file mode 100644 index bd9e7686..00000000 --- a/Applications/VLMEval/ContentView.swift +++ /dev/null @@ -1,486 +0,0 @@ -// Copyright 2024 Apple Inc. - -import AVKit -import AsyncAlgorithms -import CoreImage -import MLX -import MLXLMCommon -import MLXVLM -import PhotosUI -import SwiftUI - -#if os(iOS) || os(visionOS) - typealias PlatformImage = UIImage -#else - typealias PlatformImage = NSImage -#endif - -let videoSystemPrompt = - "Focus only on describing the key dramatic action or notable event occurring in this video segment. Skip general context or scene-setting details unless they are crucial to understanding the main action." -let imageSystemPrompt = - "You are an image understanding model capable of describing the salient features of any image." - -struct ContentView: View { - - @State var llm = VLMEvaluator() - @Environment(DeviceStat.self) private var deviceStat - - @State private var selectedImage: PlatformImage? = nil { - didSet { - if selectedImage != nil { - selectedVideoURL = nil - player = nil - } - } - } - @State private var selectedVideoURL: URL? { - didSet { - if let selectedVideoURL { - player = AVPlayer(url: selectedVideoURL) - selectedImage = nil - } - } - } - @State private var showingImagePicker = false - @State private var selectedItem: PhotosPickerItem? = nil - @State private var player: AVPlayer? = nil - - private var currentImageURL: URL? { - selectedImage == nil && selectedVideoURL == nil - ? URL( - string: - "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/bee.jpg" - ) : nil - } - - var body: some View { - VStack(alignment: .leading) { - VStack { - HStack { - Text(llm.modelInfo) - .textFieldStyle(.roundedBorder) - - Spacer() - - Text(llm.stat) - } - - VStack { - if let player { - VideoPlayer(player: player) - .frame(height: 300) - .cornerRadius(12) - } else if let selectedImage { - Group { - #if os(iOS) || os(visionOS) - Image(uiImage: selectedImage) - .resizable() - #else - Image(nsImage: selectedImage) - .resizable() - #endif - } - .scaledToFit() - .cornerRadius(12) - .frame(height: 300) - } else if let imageURL = currentImageURL { - AsyncImage(url: imageURL) { phase in - switch phase { - case .empty: - ProgressView() - case .success(let image): - image - .resizable() - .scaledToFit() - .cornerRadius(12) - .frame(height: 200) - case .failure: - Image(systemName: "photo.badge.exclamationmark") - @unknown default: - EmptyView() - } - } - } - - HStack { - #if os(iOS) || os(visionOS) - PhotosPicker( - selection: $selectedItem, - matching: PHPickerFilter.any(of: [ - PHPickerFilter.images, PHPickerFilter.videos, - ]) - ) { - Label("Select Image/Video", systemImage: "photo.badge.plus") - } - .onChange(of: selectedItem) { - Task { - if let video = try? await selectedItem?.loadTransferable( - type: TransferableVideo.self) - { - selectedVideoURL = video.url - } else if let data = try? await selectedItem?.loadTransferable( - type: Data.self) - { - selectedImage = PlatformImage(data: data) - } - } - } - #else - Button("Select Image/Video") { - showingImagePicker = true - } - .fileImporter( - isPresented: $showingImagePicker, - allowedContentTypes: [.image, .movie] - ) { result in - switch result { - case .success(let file): - Task { @MainActor in - do { - let data = try loadData(from: file) - if let image = PlatformImage(data: data) { - selectedImage = image - } else if let fileType = UTType( - filenameExtension: file.pathExtension), - fileType.conforms(to: .movie) - { - if let sandboxURL = try? loadVideoToSandbox( - from: file) - { - selectedVideoURL = sandboxURL - } - } else { - print("Failed to create image from data") - } - } catch { - print( - "Failed to load image: \(error.localizedDescription)" - ) - } - } - case .failure(let error): - print(error.localizedDescription) - } - } - #endif - - if selectedImage != nil { - Button("Clear", role: .destructive) { - selectedImage = nil - selectedItem = nil - } - } - } - } - .padding() - - HStack { - Spacer() - if llm.running { - ProgressView() - .frame(maxHeight: 20) - Spacer() - } - } - } - - ScrollView(.vertical) { - ScrollViewReader { sp in - Text(llm.output) - .textSelection(.enabled) - .onChange(of: llm.output) { _, _ in - sp.scrollTo("bottom") - } - - Spacer() - .frame(width: 1, height: 1) - .id("bottom") - } - } - .frame(minHeight: 200) - - HStack { - TextField("prompt", text: Bindable(llm).prompt) - .onSubmit(generate) - .disabled(llm.running) - #if os(visionOS) - .textFieldStyle(.roundedBorder) - #endif - Button(llm.running ? "stop" : "generate", action: llm.running ? cancel : generate) - } - } - .onAppear { - selectedVideoURL = URL( - string: - "https://videos.pexels.com/video-files/4066325/4066325-uhd_2560_1440_24fps.mp4")! - } - #if os(visionOS) - .padding(40) - #else - .padding() - #endif - .toolbar { - ToolbarItem { - Label( - "Memory Usage: \(deviceStat.gpuUsage.activeMemory.formatted(.byteCount(style: .memory)))", - systemImage: "info.circle.fill" - ) - .labelStyle(.titleAndIcon) - .padding(.horizontal) - .help( - Text( - """ - Active Memory: \(deviceStat.gpuUsage.activeMemory.formatted(.byteCount(style: .memory)))/\(GPU.memoryLimit.formatted(.byteCount(style: .memory))) - Cache Memory: \(deviceStat.gpuUsage.cacheMemory.formatted(.byteCount(style: .memory)))/\(GPU.cacheLimit.formatted(.byteCount(style: .memory))) - Peak Memory: \(deviceStat.gpuUsage.peakMemory.formatted(.byteCount(style: .memory))) - """ - ) - ) - } - ToolbarItem(placement: .primaryAction) { - Button { - Task { - copyToClipboard(llm.output) - } - } label: { - Label("Copy Output", systemImage: "doc.on.doc.fill") - } - .disabled(llm.output == "") - .labelStyle(.titleAndIcon) - } - } - .task { - _ = try? await llm.load() - } - } - - private func generate() { - Task { - if let selectedImage = selectedImage { - #if os(iOS) || os(visionOS) - let ciImage = CIImage(image: selectedImage) - llm.generate(image: ciImage ?? CIImage(), videoURL: nil) - #else - if let cgImage = selectedImage.cgImage( - forProposedRect: nil, context: nil, hints: nil) - { - let ciImage = CIImage(cgImage: cgImage) - llm.generate(image: ciImage, videoURL: nil) - } - #endif - } else if let imageURL = currentImageURL { - do { - let (data, _) = try await URLSession.shared.data(from: imageURL) - if let ciImage = CIImage(data: data) { - llm.generate(image: ciImage, videoURL: nil) - } - } catch { - print("Failed to load image: \(error.localizedDescription)") - } - } else { - if let videoURL = selectedVideoURL { - llm.generate(image: nil, videoURL: videoURL) - } - } - } - } - - private func cancel() { - llm.cancelGeneration() - } - - #if os(macOS) - private func loadData(from url: URL) throws -> Data { - guard url.startAccessingSecurityScopedResource() else { - throw NSError( - domain: "FileAccess", code: -1, - userInfo: [NSLocalizedDescriptionKey: "Failed to access the file."]) - } - defer { url.stopAccessingSecurityScopedResource() } - return try Data(contentsOf: url) - } - - private func loadVideoToSandbox(from url: URL) throws -> URL { - guard url.startAccessingSecurityScopedResource() else { - throw NSError( - domain: "FileAccess", code: -1, - userInfo: [NSLocalizedDescriptionKey: "Failed to access the file."]) - } - defer { url.stopAccessingSecurityScopedResource() } - let sandboxURL = try SandboxFileTransfer.transferFileToTemp(from: url) - return sandboxURL - } - #endif - - private func copyToClipboard(_ string: String) { - #if os(macOS) - NSPasteboard.general.clearContents() - NSPasteboard.general.setString(string, forType: .string) - #else - UIPasteboard.general.string = string - #endif - } -} - -@Observable -@MainActor -class VLMEvaluator { - - var running = false - - var prompt = "" - var output = "" - var modelInfo = "" - var stat = "" - - /// This controls which model loads. `smolvlm` is very small even unquantized, so it will fit on - /// more devices. - let modelConfiguration = VLMRegistry.smolvlm - - /// parameters controlling the output – use values appropriate for the model selected above - let generateParameters = MLXLMCommon.GenerateParameters( - maxTokens: 800, temperature: 0.7, topP: 0.9) - let updateInterval = Duration.seconds(0.25) - - /// A task responsible for handling the generation process. - var generationTask: Task? - - enum LoadState { - case idle - case loaded(ModelContainer) - } - - var loadState = LoadState.idle - - /// load and return the model -- can be called multiple times, subsequent calls will - /// just return the loaded model - func load() async throws -> ModelContainer { - switch loadState { - case .idle: - // limit the buffer cache - MLX.GPU.set(cacheLimit: 20 * 1024 * 1024) - - let modelContainer = try await VLMModelFactory.shared.loadContainer( - configuration: modelConfiguration - ) { [modelConfiguration] progress in - Task { @MainActor in - self.modelInfo = - "Downloading \(modelConfiguration.name): \(Int(progress.fractionCompleted * 100))%" - } - } - - let numParams = await modelContainer.perform { context in - context.model.numParameters() - } - - self.prompt = modelConfiguration.defaultPrompt - self.modelInfo = "Loaded \(modelConfiguration.id). Weights: \(numParams / (1024*1024))M" - loadState = .loaded(modelContainer) - return modelContainer - - case .loaded(let modelContainer): - return modelContainer - } - } - - private func generate(prompt: String, image: CIImage?, videoURL: URL?) async { - - self.output = "" - - do { - let modelContainer = try await load() - - // each time you generate you will get something new - MLXRandom.seed(UInt64(Date.timeIntervalSinceReferenceDate * 1000)) - - try await modelContainer.perform { (context: ModelContext) -> Void in - let images: [UserInput.Image] = if let image { [.ciImage(image)] } else { [] } - let videos: [UserInput.Video] = if let videoURL { [.url(videoURL)] } else { [] } - - let systemPrompt = - if !videos.isEmpty { - videoSystemPrompt - } else if !images.isEmpty { - imageSystemPrompt - } else { "You are a helpful assistant." } - - let chat: [Chat.Message] = [ - .system(systemPrompt), - .user(prompt, images: images, videos: videos), - ] - - var userInput = UserInput(chat: chat) - userInput.processing.resize = .init(width: 448, height: 448) - - let lmInput = try await context.processor.prepare(input: userInput) - - let stream = try MLXLMCommon.generate( - input: lmInput, parameters: generateParameters, context: context) - // generate and output in batches - for await batch in stream._throttle( - for: updateInterval, reducing: Generation.collect) - { - let output = batch.compactMap { $0.chunk }.joined(separator: "") - if !output.isEmpty { - Task { @MainActor [output] in - self.output += output - } - } - - if let completion = batch.compactMap({ $0.info }).first { - Task { @MainActor in - self.stat = "\(completion.tokensPerSecond) tokens/s" - } - } - } - } - } catch { - output = "Failed: \(error)" - } - } - - func generate(image: CIImage?, videoURL: URL?) { - guard !running else { return } - let currentPrompt = prompt - prompt = "" - generationTask = Task { - running = true - await generate(prompt: currentPrompt, image: image, videoURL: videoURL) - running = false - } - } - - func cancelGeneration() { - generationTask?.cancel() - running = false - } -} - -#if os(iOS) || os(visionOS) - struct TransferableVideo: Transferable { - let url: URL - - static var transferRepresentation: some TransferRepresentation { - FileRepresentation(contentType: .movie) { movie in - SentTransferredFile(movie.url) - } importing: { received in - let sandboxURL = try SandboxFileTransfer.transferFileToTemp(from: received.file) - return .init(url: sandboxURL) - } - } - } -#endif - -struct SandboxFileTransfer { - static func transferFileToTemp(from sourceURL: URL) throws -> URL { - let tempDir = FileManager.default.temporaryDirectory - let sandboxURL = tempDir.appendingPathComponent(sourceURL.lastPathComponent) - - if FileManager.default.fileExists(atPath: sandboxURL.path()) { - try FileManager.default.removeItem(at: sandboxURL) - } - - try FileManager.default.copyItem(at: sourceURL, to: sandboxURL) - return sandboxURL - } -} diff --git a/Applications/VLMEval/Preview Content/Preview Assets.xcassets/Contents.json b/Applications/VLMEval/Preview Content/Preview Assets.xcassets/Contents.json deleted file mode 100644 index 73c00596..00000000 --- a/Applications/VLMEval/Preview Content/Preview Assets.xcassets/Contents.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "info" : { - "author" : "xcode", - "version" : 1 - } -} diff --git a/Applications/VLMEval/README.md b/Applications/VLMEval/README.md deleted file mode 100644 index a7b6926c..00000000 --- a/Applications/VLMEval/README.md +++ /dev/null @@ -1,43 +0,0 @@ -# VLMEval - -An example that: - -- downloads a vision language model (SmolVLM2) -- processes an image or a video with a prompt - -You will need to set the Team on the VLMEval target in order to build and run on macOS. - -Some notes about the setup: - -- This downloads models from hugging face so VLMEval -> Signing & Capabilities has the "Outgoing Connections (Client)" set in the App Sandbox -- VLM models are large so this uses significant memory -- The example can process image, video and provides detailed analysis - -### Image Processing - -The example application uses SmolVLM2 model by default, see [ContentView.swift](ContentView.swift): - -```swift -self.modelContainer = try await VLMModelFactory.shared.loadContainer( - configuration: VLMRegistry.smolvlm) -``` - -The application: -1. Downloads a sample image -2. Processes it through the vision language model -3. Describes the images based on the prompt, providing detailed analysis of the content, objects, colors, and composition. - -### Troubleshooting - -If the program crashes with a very deep stack trace you may need to build -in Release configuration. This seems to depend on the size of the model. - -There are a couple options: - -- Build Release -- Force the model evaluation to run on the main thread, e.g. using @MainActor -- Build `Cmlx` with optimizations by modifying `mlx/Package.swift` and adding `.unsafeOptions(["-O3"]),` - -### Performance - -You may find that running outside the debugger boosts performance. You can do this in Xcode by pressing cmd-opt-r and unchecking "Debug Executable". diff --git a/Applications/VLMEval/VLMEvalApp.swift b/Applications/VLMEval/VLMEvalApp.swift deleted file mode 100644 index 1d1d8e8e..00000000 --- a/Applications/VLMEval/VLMEvalApp.swift +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright © 2024 Apple Inc. - -import SwiftUI - -@main -struct VLMEvalApp: App { - var body: some Scene { - WindowGroup { - ContentView() - .environment(DeviceStat()) - } - } -} diff --git a/Package.swift b/Package.swift index 1cb71722..493b6b80 100644 --- a/Package.swift +++ b/Package.swift @@ -31,7 +31,6 @@ let package = Package( .product(name: "MLXNN", package: "mlx-swift"), .product(name: "MLXOptimizers", package: "mlx-swift"), .product(name: "MLXRandom", package: "mlx-swift"), - .product(name: "Transformers", package: "swift-transformers"), .product(name: "Gzip", package: "GzipSwift"), ], path: "Libraries/MLXMNIST", diff --git a/README.md b/README.md index 64ad55a1..f078adb5 100644 --- a/README.md +++ b/README.md @@ -7,12 +7,13 @@ examples use models implemented in [MLX Swift LM](https://github.com/ml-explore/ both iOS and macOS that downloads MNIST training data and trains a [LeNet](https://en.wikipedia.org/wiki/LeNet). +- [LLMBasic](Applications/LLMBasic/README.md): A **minimal** LLM chat example + application. It has only two features: load the model and evaluate a prompt. + - [LLMEval](Applications/LLMEval/README.md): An example that runs on both iOS and macOS that downloads an LLM and tokenizer from Hugging Face and - generates text from a given prompt. - -- [VLMEval](Applications/VLMEval/README.md): An example that runs on iOS, macOS and visionOS to download a VLM and tokenizer from Hugging Face and - analyzes the given image and describe it in text. + generates text from a given prompt. It has some preset prompts, tool integration, + etc. Additionally it shows detailed statistics on the run. - [MLXChatExample](Applications/MLXChatExample/README.md): An example chat app that runs on both iOS and macOS that supports LLMs and VLMs. @@ -28,7 +29,7 @@ examples use models implemented in [MLX Swift LM](https://github.com/ml-explore/ - [llm-tool](Tools/llm-tool/README.md): A command line tool for generating text using a variety of LLMs available on the Hugging Face hub. -- [ExampleLLM](Tools/ExampleLLM/README.md): A command line tool using the simplified API to interact with LLMs. +- [ExampleLLM](Tools/ExampleLLM/README.md): A command line tool using the simplified API to interact with LLMs. See also `LLMBasic`. - [image-tool](Tools/image-tool/README.md): A command line tool for generating images using a stable diffusion model from Hugging Face. diff --git a/mlx-swift-examples.xcodeproj/project.pbxproj b/mlx-swift-examples.xcodeproj/project.pbxproj index 5230c017..e5e0531c 100644 --- a/mlx-swift-examples.xcodeproj/project.pbxproj +++ b/mlx-swift-examples.xcodeproj/project.pbxproj @@ -3,38 +3,22 @@ archiveVersion = 1; classes = { }; - objectVersion = 70; + objectVersion = 71; objects = { /* Begin PBXBuildFile section */ - 0A8284222D13863900BEF338 /* MLXVLM in Frameworks */ = {isa = PBXBuildFile; productRef = 0AC74ED92D136223003C90A7 /* MLXVLM */; }; 0A979CD92E9717C500635D67 /* ArgumentParser in Frameworks */ = {isa = PBXBuildFile; productRef = 0A979CD82E9717C500635D67 /* ArgumentParser */; }; 0A979D132E9743D800635D67 /* MLXEmbedders in Frameworks */ = {isa = PBXBuildFile; productRef = 0A979D122E9743D800635D67 /* MLXEmbedders */; }; - 0AC74ECF2D13622A003C90A7 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0AC74EC92D13622A003C90A7 /* Preview Assets.xcassets */; }; - 0AC74ED02D13622A003C90A7 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0AC74ECB2D13622A003C90A7 /* Assets.xcassets */; }; - 0AC74ED12D13622A003C90A7 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AC74ECC2D13622A003C90A7 /* ContentView.swift */; }; - 0AC74ED22D13622A003C90A7 /* VLMEvalApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AC74ECD2D13622A003C90A7 /* VLMEvalApp.swift */; }; 0F5AD8002DB70E6300745C06 /* MLXLLM in Frameworks */ = {isa = PBXBuildFile; productRef = C32A17FC2CFFB98A0092A5B6 /* MLXLLM */; }; 0F5AD8012DB70E6300745C06 /* MLXVLM in Frameworks */ = {isa = PBXBuildFile; productRef = C32A17FE2CFFB98A0092A5B6 /* MLXVLM */; }; - 12305EAF2B9D864400C92FEE /* PredictionView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 12305EAE2B9D864400C92FEE /* PredictionView.swift */; }; - 6C5EF5D82EEA33FA00134C83 /* AppIcon.icon in Resources */ = {isa = PBXBuildFile; fileRef = 6C5EF5D72EEA33FA00134C83 /* AppIcon.icon */; }; - 6C5EF5DC2EEA35B700134C83 /* AssetCatalog.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6C5EF5DB2EEA35B700134C83 /* AssetCatalog.xcassets */; }; 81695B412BA373D300F260D8 /* MarkdownUI in Frameworks */ = {isa = PBXBuildFile; productRef = 81695B402BA373D300F260D8 /* MarkdownUI */; }; - C3056BAE2BCD97B700A31D04 /* LoRATrainingExampleApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3056BAD2BCD97B700A31D04 /* LoRATrainingExampleApp.swift */; }; - C3056BB02BCD97B700A31D04 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3056BAF2BCD97B700A31D04 /* ContentView.swift */; }; - C3056BB22BCD97B800A31D04 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C3056BB12BCD97B800A31D04 /* Assets.xcassets */; }; - C3056BB62BCD97B800A31D04 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C3056BB52BCD97B800A31D04 /* Preview Assets.xcassets */; }; - C3056BBA2BCD981900A31D04 /* train.jsonl in Resources */ = {isa = PBXBuildFile; fileRef = C3056BA22BCD973400A31D04 /* train.jsonl */; }; - C3056BBB2BCD981900A31D04 /* test.jsonl in Resources */ = {isa = PBXBuildFile; fileRef = C3056BA12BCD973400A31D04 /* test.jsonl */; }; - C3056BBC2BCD981900A31D04 /* valid.jsonl in Resources */ = {isa = PBXBuildFile; fileRef = C3056BA32BCD973400A31D04 /* valid.jsonl */; }; - C3132C2C2DFB301A00270E8E /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3132C2A2DFB301A00270E8E /* main.swift */; }; C3132C2E2DFB317C00270E8E /* MLXVLM in Frameworks */ = {isa = PBXBuildFile; productRef = C3132C2D2DFB317C00270E8E /* MLXVLM */; }; C3132C302DFB317C00270E8E /* MLXLLM in Frameworks */ = {isa = PBXBuildFile; productRef = C3132C2F2DFB317C00270E8E /* MLXLLM */; }; + C314FFE42EF33D0900E5B73A /* MLXLLM in Frameworks */ = {isa = PBXBuildFile; productRef = C314FFE32EF33D0900E5B73A /* MLXLLM */; }; C3208E762DB1945D006AE6CA /* MLX in Frameworks */ = {isa = PBXBuildFile; productRef = C3208E752DB1945D006AE6CA /* MLX */; }; C3208E7A2DB1945D006AE6CA /* MLXNN in Frameworks */ = {isa = PBXBuildFile; productRef = C3208E792DB1945D006AE6CA /* MLXNN */; }; C3208E7B2DB194ED006AE6CA /* MLXLLM in Frameworks */ = {isa = PBXBuildFile; productRef = C32A17FC2CFFB98A0092A5B6 /* MLXLLM */; }; C3208ED02DB195A7006AE6CA /* MLXVLM in Frameworks */ = {isa = PBXBuildFile; productRef = C32A17FE2CFFB98A0092A5B6 /* MLXVLM */; }; - C3288D762B6D9313009FF608 /* LinearModelTraining.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3288D752B6D9313009FF608 /* LinearModelTraining.swift */; }; C3288D7B2B6D9339009FF608 /* ArgumentParser in Frameworks */ = {isa = PBXBuildFile; productRef = C3288D7A2B6D9339009FF608 /* ArgumentParser */; }; C32A18012CFFD1810092A5B6 /* MLXMNIST in Frameworks */ = {isa = PBXBuildFile; productRef = C32A18002CFFD1810092A5B6 /* MLXMNIST */; }; C32A18032CFFD1920092A5B6 /* MLXMNIST in Frameworks */ = {isa = PBXBuildFile; productRef = C32A18022CFFD1920092A5B6 /* MLXMNIST */; }; @@ -47,31 +31,10 @@ C32A184C2D00E1540092A5B6 /* MLXOptimizers in Frameworks */ = {isa = PBXBuildFile; productRef = C32A184B2D00E1540092A5B6 /* MLXOptimizers */; }; C32AA20C2EB977C4002914C6 /* MLXLLM in Frameworks */ = {isa = PBXBuildFile; productRef = C32AA20B2EB977C4002914C6 /* MLXLLM */; }; C32AA20E2EB977C4002914C6 /* MLXVLM in Frameworks */ = {isa = PBXBuildFile; productRef = C32AA20D2EB977C4002914C6 /* MLXVLM */; }; - C32B4C6D2DA7136000EF663D /* AsyncAlgorithms in Frameworks */ = {isa = PBXBuildFile; productRef = C32B4C6C2DA7136000EF663D /* AsyncAlgorithms */; }; - C32B4C6F2DA71ADC00EF663D /* AsyncAlgorithms in Frameworks */ = {isa = PBXBuildFile; productRef = C32B4C6E2DA71ADC00EF663D /* AsyncAlgorithms */; }; - C34E48F52B696F0B00FCB841 /* LLMTool.swift in Sources */ = {isa = PBXBuildFile; fileRef = C34E48F42B696F0B00FCB841 /* LLMTool.swift */; }; - C34E49242B6A026F00FCB841 /* MNISTTool.swift in Sources */ = {isa = PBXBuildFile; fileRef = C34E49232B6A026F00FCB841 /* MNISTTool.swift */; }; C34E49292B6A028100FCB841 /* ArgumentParser in Frameworks */ = {isa = PBXBuildFile; productRef = C34E49282B6A028100FCB841 /* ArgumentParser */; }; - C36BEFB52BBDEAD8002D4AFE /* LoraCommands.swift in Sources */ = {isa = PBXBuildFile; fileRef = C36BEFB32BBDEA69002D4AFE /* LoraCommands.swift */; }; - C36BEFB82BBDED51002D4AFE /* Arguments.swift in Sources */ = {isa = PBXBuildFile; fileRef = C36BEFB62BBDECBC002D4AFE /* Arguments.swift */; }; - C36BEFE32BC32988002D4AFE /* ImageTool.swift in Sources */ = {isa = PBXBuildFile; fileRef = C36BEFE22BC32988002D4AFE /* ImageTool.swift */; }; C36BEFEF2BC329C5002D4AFE /* ArgumentParser in Frameworks */ = {isa = PBXBuildFile; productRef = C36BEFEE2BC329C5002D4AFE /* ArgumentParser */; }; C36BEFF22BC32A9A002D4AFE /* Progress in Frameworks */ = {isa = PBXBuildFile; productRef = C36BEFF12BC32A9A002D4AFE /* Progress */; }; - C36BF0042BC5CE55002D4AFE /* StableDiffusionExampleApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = C36BF0032BC5CE55002D4AFE /* StableDiffusionExampleApp.swift */; }; - C36BF0062BC5CE55002D4AFE /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C36BF0052BC5CE55002D4AFE /* ContentView.swift */; }; - C36BF0082BC5CE56002D4AFE /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C36BF0072BC5CE56002D4AFE /* Assets.xcassets */; }; - C36BF00C2BC5CE56002D4AFE /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C36BF00B2BC5CE56002D4AFE /* Preview Assets.xcassets */; }; - C36BF0352BC70F11002D4AFE /* Arguments.swift in Sources */ = {isa = PBXBuildFile; fileRef = C36BF0342BC70F11002D4AFE /* Arguments.swift */; }; - C37133A22DD6524B00D19830 /* ListCommands.swift in Sources */ = {isa = PBXBuildFile; fileRef = C37133A12DD6524B00D19830 /* ListCommands.swift */; }; - C38BA3AA2DB8321600BAFA88 /* Chat.swift in Sources */ = {isa = PBXBuildFile; fileRef = C38BA3A92DB8321600BAFA88 /* Chat.swift */; }; - C392737D2B606A1D00368D5D /* Tutorial.swift in Sources */ = {isa = PBXBuildFile; fileRef = C392737C2B606A1D00368D5D /* Tutorial.swift */; }; C397C59C2B62C6D0004B084D /* ArgumentParser in Frameworks */ = {isa = PBXBuildFile; productRef = C397C59B2B62C6D0004B084D /* ArgumentParser */; }; - C3A8B3CB2B92951E0002EFB8 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C3A8B3C32B92951E0002EFB8 /* Assets.xcassets */; }; - C3A8B3CC2B92951E0002EFB8 /* MNISTTrainerApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3A8B3C42B92951E0002EFB8 /* MNISTTrainerApp.swift */; }; - C3A8B3CD2B92951E0002EFB8 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C3A8B3C62B92951E0002EFB8 /* Preview Assets.xcassets */; }; - C3A8B3CF2B92951E0002EFB8 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3A8B3C92B92951E0002EFB8 /* ContentView.swift */; }; - C3A8B3F42B92A2A90002EFB8 /* LLMEvalApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3A8B3ED2B92A2A90002EFB8 /* LLMEvalApp.swift */; }; - C3C7C4FB2DB19026000373CF /* AVKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C3C7C4FA2DB19026000373CF /* AVKit.framework */; }; C3E7D94D2CF6C9B20056C095 /* StableDiffusion in Frameworks */ = {isa = PBXBuildFile; productRef = C3E7D94C2CF6C9B20056C095 /* StableDiffusion */; }; /* End PBXBuildFile section */ @@ -213,79 +176,196 @@ /* Begin PBXFileReference section */ 0A979CD12E97175800635D67 /* embedder-tool */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "embedder-tool"; sourceTree = BUILT_PRODUCTS_DIR; }; - 0AC74EBB2D136221003C90A7 /* VLMEval.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = VLMEval.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 0AC74EC92D13622A003C90A7 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; - 0AC74ECB2D13622A003C90A7 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - 0AC74ECC2D13622A003C90A7 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; - 0AC74ECD2D13622A003C90A7 /* VLMEvalApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VLMEvalApp.swift; sourceTree = ""; }; - 0AC74ED42D13630D003C90A7 /* VLMEval.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = VLMEval.entitlements; sourceTree = ""; }; - 0AC74F282D1376F1003C90A7 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; 0F5AD7412DB70C0300745C06 /* MLXChatExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MLXChatExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 12305EAE2B9D864400C92FEE /* PredictionView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PredictionView.swift; sourceTree = ""; }; - 6C5EF5D72EEA33FA00134C83 /* AppIcon.icon */ = {isa = PBXFileReference; lastKnownFileType = folder.iconcomposer.icon; path = AppIcon.icon; sourceTree = ""; }; - 6C5EF5DB2EEA35B700134C83 /* AssetCatalog.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = AssetCatalog.xcassets; sourceTree = ""; }; - C3056BA12BCD973400A31D04 /* test.jsonl */ = {isa = PBXFileReference; lastKnownFileType = text; path = test.jsonl; sourceTree = ""; }; - C3056BA22BCD973400A31D04 /* train.jsonl */ = {isa = PBXFileReference; lastKnownFileType = text; path = train.jsonl; sourceTree = ""; }; - C3056BA32BCD973400A31D04 /* valid.jsonl */ = {isa = PBXFileReference; lastKnownFileType = text; path = valid.jsonl; sourceTree = ""; }; - C3056BA42BCD973400A31D04 /* wikisql.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; path = wikisql.py; sourceTree = ""; }; C3056BAB2BCD97B700A31D04 /* LoRATrainingExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = LoRATrainingExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; - C3056BAD2BCD97B700A31D04 /* LoRATrainingExampleApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoRATrainingExampleApp.swift; sourceTree = ""; }; - C3056BAF2BCD97B700A31D04 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; - C3056BB12BCD97B800A31D04 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - C3056BB32BCD97B800A31D04 /* LoRATrainingExample.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = LoRATrainingExample.entitlements; sourceTree = ""; }; - C3056BB52BCD97B800A31D04 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; - C3056BC42BCDAB8600A31D04 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; C3132C232DFB2FFB00270E8E /* ExampleLLM */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = ExampleLLM; sourceTree = BUILT_PRODUCTS_DIR; }; - C3132C2A2DFB301A00270E8E /* main.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = ""; }; + C314FEDB2EF33B2F00E5B73A /* LLMBasic.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = LLMBasic.app; sourceTree = BUILT_PRODUCTS_DIR; }; C3208E6E2DB19451006AE6CA /* MLXLMTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MLXLMTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; C325DE3F2B648CDB00628871 /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; C3288D732B6D9313009FF608 /* LinearModelTraining */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = LinearModelTraining; sourceTree = BUILT_PRODUCTS_DIR; }; - C3288D752B6D9313009FF608 /* LinearModelTraining.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LinearModelTraining.swift; sourceTree = ""; }; - C3288D842B6D94BD009FF608 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; - C34E48F42B696F0B00FCB841 /* LLMTool.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LLMTool.swift; sourceTree = ""; }; - C34E48F92B69930300FCB841 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; C34E49212B6A026F00FCB841 /* mnist-tool */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "mnist-tool"; sourceTree = BUILT_PRODUCTS_DIR; }; - C34E49232B6A026F00FCB841 /* MNISTTool.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MNISTTool.swift; sourceTree = ""; }; - C36BEFB32BBDEA69002D4AFE /* LoraCommands.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoraCommands.swift; sourceTree = ""; }; - C36BEFB62BBDECBC002D4AFE /* Arguments.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Arguments.swift; sourceTree = ""; }; C36BEFE02BC32988002D4AFE /* image-tool */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "image-tool"; sourceTree = BUILT_PRODUCTS_DIR; }; - C36BEFE22BC32988002D4AFE /* ImageTool.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageTool.swift; sourceTree = ""; }; C36BF0012BC5CE55002D4AFE /* StableDiffusionExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = StableDiffusionExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; - C36BF0032BC5CE55002D4AFE /* StableDiffusionExampleApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StableDiffusionExampleApp.swift; sourceTree = ""; }; - C36BF0052BC5CE55002D4AFE /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; - C36BF0072BC5CE56002D4AFE /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - C36BF0092BC5CE56002D4AFE /* StableDiffusionExample.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = StableDiffusionExample.entitlements; sourceTree = ""; }; - C36BF00B2BC5CE56002D4AFE /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; - C36BF0342BC70F11002D4AFE /* Arguments.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Arguments.swift; sourceTree = ""; }; - C37133A12DD6524B00D19830 /* ListCommands.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListCommands.swift; sourceTree = ""; }; - C38BA3A92DB8321600BAFA88 /* Chat.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Chat.swift; sourceTree = ""; }; C39273742B606A0A00368D5D /* Tutorial */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = Tutorial; sourceTree = BUILT_PRODUCTS_DIR; }; - C392737C2B606A1D00368D5D /* Tutorial.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Tutorial.swift; sourceTree = ""; }; C397C58B2B62C6A9004B084D /* llm-tool */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = "llm-tool"; sourceTree = BUILT_PRODUCTS_DIR; }; - C3A5CCF52DFB8FFC004708FF /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; C3A8B3B22B9295090002EFB8 /* MNISTTrainer.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MNISTTrainer.app; sourceTree = BUILT_PRODUCTS_DIR; }; - C3A8B3C22B92951E0002EFB8 /* MNISTTrainer-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "MNISTTrainer-Info.plist"; sourceTree = ""; }; - C3A8B3C32B92951E0002EFB8 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - C3A8B3C42B92951E0002EFB8 /* MNISTTrainerApp.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MNISTTrainerApp.swift; sourceTree = ""; }; - C3A8B3C62B92951E0002EFB8 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; - C3A8B3C72B92951E0002EFB8 /* MNISTTrainer.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = MNISTTrainer.entitlements; sourceTree = ""; }; - C3A8B3C82B92951E0002EFB8 /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; - C3A8B3C92B92951E0002EFB8 /* ContentView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; C3A8B3DC2B92A29E0002EFB8 /* LLMEval.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = LLMEval.app; sourceTree = BUILT_PRODUCTS_DIR; }; - C3A8B3ED2B92A2A90002EFB8 /* LLMEvalApp.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LLMEvalApp.swift; sourceTree = ""; }; - C3A8B3F02B92A2A90002EFB8 /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; - C3A8B3F12B92A2A90002EFB8 /* LLMEval.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = LLMEval.entitlements; sourceTree = ""; }; - C3C3240B2B6CA689007D2D9A /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; - C3C36A6B2CA714600099FFA4 /* Build.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Build.xcconfig; sourceTree = ""; }; C3C7C4D92DB16C83000373CF /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS18.4.sdk/System/Library/Frameworks/AVFoundation.framework; sourceTree = DEVELOPER_DIR; }; C3C7C4DB2DB16C89000373CF /* CoreImage.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreImage.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS18.4.sdk/System/Library/Frameworks/CoreImage.framework; sourceTree = DEVELOPER_DIR; }; C3C7C4DD2DB16CA2000373CF /* CoreAudioTypes.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudioTypes.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS18.4.sdk/System/Library/Frameworks/CoreAudioTypes.framework; sourceTree = DEVELOPER_DIR; }; C3C7C4FA2DB19026000373CF /* AVKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS18.4.sdk/System/Library/Frameworks/AVKit.framework; sourceTree = DEVELOPER_DIR; }; - C3D573052C40701E00857A35 /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; F8D7023A2BB4E223003D7CF5 /* Package.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Package.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */ + C314FCFB2EF3314200E5B73A /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = { + isa = PBXFileSystemSynchronizedBuildFileExceptionSet; + membershipExceptions = ( + lora/wikisql.py, + ); + target = C3056BAA2BCD97B700A31D04 /* LoRATrainingExample */; + }; + C314FD412EF3315100E5B73A /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = { + isa = PBXFileSystemSynchronizedBuildFileExceptionSet; + membershipExceptions = ( + Tutorial/Tutorial.swift, + ); + target = C39273732B606A0A00368D5D /* Tutorial */; + }; + C314FD422EF3315100E5B73A /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = { + isa = PBXFileSystemSynchronizedBuildFileExceptionSet; + membershipExceptions = ( + "llm-tool/Arguments.swift", + "llm-tool/Chat.swift", + "llm-tool/ListCommands.swift", + "llm-tool/LLMTool.swift", + "llm-tool/LoraCommands.swift", + ); + target = C397C58A2B62C6A9004B084D /* llm-tool */; + }; + C314FD432EF3315100E5B73A /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = { + isa = PBXFileSystemSynchronizedBuildFileExceptionSet; + membershipExceptions = ( + "mnist-tool/MNISTTool.swift", + ); + target = C34E49202B6A026F00FCB841 /* mnist-tool */; + }; + C314FD442EF3315100E5B73A /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = { + isa = PBXFileSystemSynchronizedBuildFileExceptionSet; + membershipExceptions = ( + "embedder-tool/ArgumentSupport.swift", + "embedder-tool/CommandError.swift", + "embedder-tool/CorpusArguments.swift", + "embedder-tool/DemoCommand.swift", + "embedder-tool/Diagnostics.swift", + "embedder-tool/EmbedderCommand.swift", + "embedder-tool/EmbedderRuntime+Embedding.swift", + "embedder-tool/EmbedderTool.swift", + "embedder-tool/Indexing.swift", + "embedder-tool/ListCommand.swift", + "embedder-tool/MemoryArguments.swift", + "embedder-tool/ModelArguments.swift", + "embedder-tool/PoolingArguments.swift", + "embedder-tool/PoolingSupport.swift", + "embedder-tool/ReplCommand.swift", + "embedder-tool/SearchCommand.swift", + "embedder-tool/VectorOperations.swift", + ); + target = 0A979CD02E97175800635D67 /* embedder-tool */; + }; + C314FD452EF3315100E5B73A /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = { + isa = PBXFileSystemSynchronizedBuildFileExceptionSet; + membershipExceptions = ( + LinearModelTraining/LinearModelTraining.swift, + ); + target = C3288D722B6D9313009FF608 /* LinearModelTraining */; + }; + C314FD462EF3315100E5B73A /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = { + isa = PBXFileSystemSynchronizedBuildFileExceptionSet; + membershipExceptions = ( + "image-tool/Arguments.swift", + "image-tool/ImageTool.swift", + ); + target = C36BEFDF2BC32988002D4AFE /* image-tool */; + }; + C314FD472EF3315100E5B73A /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = { + isa = PBXFileSystemSynchronizedBuildFileExceptionSet; + membershipExceptions = ( + ExampleLLM/main.swift, + ); + target = C3132C222DFB2FFB00270E8E /* ExampleLLM */; + }; + C314FDD82EF3315A00E5B73A /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = { + isa = PBXFileSystemSynchronizedBuildFileExceptionSet; + membershipExceptions = ( + LLMEval/AppIcon.icon, + LLMEval/AssetCatalog.xcassets, + LLMEval/LLMEvalApp.swift, + LLMEval/Models/CarKeysStory.md, + LLMEval/Models/LongPrompt.md, + LLMEval/Models/PresetPrompts.swift, + LLMEval/Models/ToolDefinitions.swift, + LLMEval/Services/FormatUtilities.swift, + LLMEval/Services/ToolExecutor.swift, + LLMEval/ViewModels/DeviceStat.swift, + LLMEval/ViewModels/LLMEvaluator.swift, + LLMEval/Views/ContentView.swift, + LLMEval/Views/HeaderView.swift, + LLMEval/Views/LoadingOverlayView.swift, + LLMEval/Views/MetricCard.swift, + LLMEval/Views/MetricsView.swift, + LLMEval/Views/OutputView.swift, + LLMEval/Views/PresetPromptsSheet.swift, + LLMEval/Views/PromptInputView.swift, + ); + target = C3A8B3DB2B92A29D0002EFB8 /* LLMEval */; + }; + C314FDDA2EF3315A00E5B73A /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = { + isa = PBXFileSystemSynchronizedBuildFileExceptionSet; + membershipExceptions = ( + MLXChatExample/ChatView.swift, + MLXChatExample/MLXChatExampleApp.swift, + MLXChatExample/Models/LMModel.swift, + MLXChatExample/Models/Message.swift, + MLXChatExample/Services/MLXService.swift, + MLXChatExample/Support/Assets.xcassets, + "MLXChatExample/Support/HubApi+default.swift", + "MLXChatExample/Support/Preview Content/Preview Assets.xcassets", + MLXChatExample/Support/SampleData.swift, + MLXChatExample/ViewModels/ChatViewModel.swift, + MLXChatExample/Views/ConversationView.swift, + MLXChatExample/Views/MediaPreviewView.swift, + MLXChatExample/Views/MessageView.swift, + MLXChatExample/Views/PromptField.swift, + MLXChatExample/Views/Toolbar/ChatToolbarView.swift, + MLXChatExample/Views/Toolbar/DownloadProgressView.swift, + MLXChatExample/Views/Toolbar/ErrorView.swift, + MLXChatExample/Views/Toolbar/GenerationInfoView.swift, + ); + target = 0F5AD7402DB70C0300745C06 /* MLXChatExample */; + }; + C314FDDB2EF3315A00E5B73A /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = { + isa = PBXFileSystemSynchronizedBuildFileExceptionSet; + membershipExceptions = ( + MNISTTrainer/Assets.xcassets, + MNISTTrainer/ContentView.swift, + MNISTTrainer/MNISTTrainerApp.swift, + MNISTTrainer/PredictionView.swift, + "MNISTTrainer/Preview Content/Preview Assets.xcassets", + ); + target = C3A8B3B12B9295090002EFB8 /* MNISTTrainer */; + }; + C314FDDC2EF3315A00E5B73A /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = { + isa = PBXFileSystemSynchronizedBuildFileExceptionSet; + membershipExceptions = ( + LoRATrainingExample/Assets.xcassets, + LoRATrainingExample/ContentView.swift, + LoRATrainingExample/LoRATrainingExampleApp.swift, + "LoRATrainingExample/Preview Content/Preview Assets.xcassets", + ); + target = C3056BAA2BCD97B700A31D04 /* LoRATrainingExample */; + }; + C314FDDD2EF3315A00E5B73A /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = { + isa = PBXFileSystemSynchronizedBuildFileExceptionSet; + membershipExceptions = ( + StableDiffusionExample/Assets.xcassets, + StableDiffusionExample/ContentView.swift, + "StableDiffusionExample/Preview Content/Preview Assets.xcassets", + StableDiffusionExample/StableDiffusionExampleApp.swift, + ); + target = C36BF0002BC5CE55002D4AFE /* StableDiffusionExample */; + }; + C314FEED2EF33B3900E5B73A /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = { + isa = PBXFileSystemSynchronizedBuildFileExceptionSet; + membershipExceptions = ( + LLMBasic/Assets.xcassets, + LLMBasic/ChatModel.swift, + LLMBasic/ContentView.swift, + LLMBasic/LLMBasicApp.swift, + LLMBasic/README.md, + ); + target = C314FEDA2EF33B2F00E5B73A /* LLMBasic */; + }; C3208F272DB19614006AE6CA /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = { isa = PBXFileSystemSynchronizedBuildFileExceptionSet; membershipExceptions = ( @@ -300,12 +380,10 @@ /* End PBXFileSystemSynchronizedBuildFileExceptionSet section */ /* Begin PBXFileSystemSynchronizedRootGroup section */ - 0A979CD22E97175800635D67 /* embedder-tool */ = {isa = PBXFileSystemSynchronizedRootGroup; explicitFileTypes = {}; explicitFolders = (); path = "embedder-tool"; sourceTree = ""; }; - 0F5AD7422DB70C0300745C06 /* MLXChatExample */ = {isa = PBXFileSystemSynchronizedRootGroup; explicitFileTypes = {}; explicitFolders = (); path = MLXChatExample; sourceTree = ""; }; - 6C5EF5A82EEA33B000134C83 /* Models */ = {isa = PBXFileSystemSynchronizedRootGroup; explicitFileTypes = {}; explicitFolders = (); path = Models; sourceTree = ""; }; - 6C5EF5BE2EEA33CD00134C83 /* ViewModels */ = {isa = PBXFileSystemSynchronizedRootGroup; explicitFileTypes = {}; explicitFolders = (); path = ViewModels; sourceTree = ""; }; - 6C5EF5C92EEA33D900134C83 /* Views */ = {isa = PBXFileSystemSynchronizedRootGroup; explicitFileTypes = {}; explicitFolders = (); path = Views; sourceTree = ""; }; - 6C5EF5D42EEA33E800134C83 /* Services */ = {isa = PBXFileSystemSynchronizedRootGroup; explicitFileTypes = {}; explicitFolders = (); path = Services; sourceTree = ""; }; + C314FCF02EF3313B00E5B73A /* Configuration */ = {isa = PBXFileSystemSynchronizedRootGroup; explicitFileTypes = {}; explicitFolders = (); path = Configuration; sourceTree = ""; }; + C314FCF62EF3314200E5B73A /* Data */ = {isa = PBXFileSystemSynchronizedRootGroup; exceptions = (C314FCFB2EF3314200E5B73A /* PBXFileSystemSynchronizedBuildFileExceptionSet */, ); explicitFileTypes = {}; explicitFolders = (); path = Data; sourceTree = ""; }; + C314FD242EF3315100E5B73A /* Tools */ = {isa = PBXFileSystemSynchronizedRootGroup; exceptions = (C314FD422EF3315100E5B73A /* PBXFileSystemSynchronizedBuildFileExceptionSet */, C314FD472EF3315100E5B73A /* PBXFileSystemSynchronizedBuildFileExceptionSet */, C314FD442EF3315100E5B73A /* PBXFileSystemSynchronizedBuildFileExceptionSet */, C314FD462EF3315100E5B73A /* PBXFileSystemSynchronizedBuildFileExceptionSet */, C314FD432EF3315100E5B73A /* PBXFileSystemSynchronizedBuildFileExceptionSet */, C314FD412EF3315100E5B73A /* PBXFileSystemSynchronizedBuildFileExceptionSet */, C314FD452EF3315100E5B73A /* PBXFileSystemSynchronizedBuildFileExceptionSet */, ); explicitFileTypes = {}; explicitFolders = (); path = Tools; sourceTree = ""; }; + C314FDA02EF3315A00E5B73A /* Applications */ = {isa = PBXFileSystemSynchronizedRootGroup; exceptions = (C314FDD82EF3315A00E5B73A /* PBXFileSystemSynchronizedBuildFileExceptionSet */, C314FDDA2EF3315A00E5B73A /* PBXFileSystemSynchronizedBuildFileExceptionSet */, C314FEED2EF33B3900E5B73A /* PBXFileSystemSynchronizedBuildFileExceptionSet */, C314FDDD2EF3315A00E5B73A /* PBXFileSystemSynchronizedBuildFileExceptionSet */, C314FDDC2EF3315A00E5B73A /* PBXFileSystemSynchronizedBuildFileExceptionSet */, C314FDDB2EF3315A00E5B73A /* PBXFileSystemSynchronizedBuildFileExceptionSet */, ); explicitFileTypes = {}; explicitFolders = (); path = Applications; sourceTree = ""; }; C397D92E2CD440EF00B87EE2 /* Libraries */ = {isa = PBXFileSystemSynchronizedRootGroup; explicitFileTypes = {}; explicitFolders = (); path = Libraries; sourceTree = ""; }; C3C7C4222DB16A02000373CF /* Tests */ = {isa = PBXFileSystemSynchronizedRootGroup; exceptions = (C3208F272DB19614006AE6CA /* PBXFileSystemSynchronizedBuildFileExceptionSet */, ); explicitFileTypes = {}; explicitFolders = (); path = Tests; sourceTree = ""; }; /* End PBXFileSystemSynchronizedRootGroup section */ @@ -320,16 +398,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 0AC74EB82D136221003C90A7 /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - C3C7C4FB2DB19026000373CF /* AVKit.framework in Frameworks */, - 0A8284222D13863900BEF338 /* MLXVLM in Frameworks */, - C32B4C6D2DA7136000EF663D /* AsyncAlgorithms in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; 0F5AD73E2DB70C0300745C06 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -356,6 +424,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + C314FED82EF33B2F00E5B73A /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + C314FFE42EF33D0900E5B73A /* MLXLLM in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; C3208E6B2DB19451006AE6CA /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -437,155 +513,23 @@ files = ( C32A18052CFFD19F0092A5B6 /* MLXLLM in Frameworks */, 81695B412BA373D300F260D8 /* MarkdownUI in Frameworks */, - C32B4C6F2DA71ADC00EF663D /* AsyncAlgorithms in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 0AC74ECA2D13622A003C90A7 /* Preview Content */ = { - isa = PBXGroup; - children = ( - 0AC74EC92D13622A003C90A7 /* Preview Assets.xcassets */, - ); - path = "Preview Content"; - sourceTree = ""; - }; - 0AC74ECE2D13622A003C90A7 /* VLMEval */ = { - isa = PBXGroup; - children = ( - 0AC74F282D1376F1003C90A7 /* README.md */, - 0AC74ED42D13630D003C90A7 /* VLMEval.entitlements */, - 0AC74ECA2D13622A003C90A7 /* Preview Content */, - 0AC74ECB2D13622A003C90A7 /* Assets.xcassets */, - 0AC74ECC2D13622A003C90A7 /* ContentView.swift */, - 0AC74ECD2D13622A003C90A7 /* VLMEvalApp.swift */, - ); - path = VLMEval; - sourceTree = ""; - }; - C3056BA52BCD973400A31D04 /* lora */ = { - isa = PBXGroup; - children = ( - C3056BA12BCD973400A31D04 /* test.jsonl */, - C3056BA22BCD973400A31D04 /* train.jsonl */, - C3056BA32BCD973400A31D04 /* valid.jsonl */, - C3056BA42BCD973400A31D04 /* wikisql.py */, - ); - path = lora; - sourceTree = ""; - }; - C3056BA62BCD973400A31D04 /* Data */ = { - isa = PBXGroup; - children = ( - C3056BA52BCD973400A31D04 /* lora */, - ); - path = Data; - sourceTree = ""; - }; - C3056BAC2BCD97B700A31D04 /* LoRATrainingExample */ = { - isa = PBXGroup; - children = ( - C3056BAD2BCD97B700A31D04 /* LoRATrainingExampleApp.swift */, - C3056BAF2BCD97B700A31D04 /* ContentView.swift */, - C3056BB12BCD97B800A31D04 /* Assets.xcassets */, - C3056BB32BCD97B800A31D04 /* LoRATrainingExample.entitlements */, - C3056BB42BCD97B800A31D04 /* Preview Content */, - C3056BC42BCDAB8600A31D04 /* README.md */, - ); - path = LoRATrainingExample; - sourceTree = ""; - }; - C3056BB42BCD97B800A31D04 /* Preview Content */ = { - isa = PBXGroup; - children = ( - C3056BB52BCD97B800A31D04 /* Preview Assets.xcassets */, - ); - path = "Preview Content"; - sourceTree = ""; - }; - C3132C2B2DFB301A00270E8E /* ExampleLLM */ = { - isa = PBXGroup; - children = ( - C3132C2A2DFB301A00270E8E /* main.swift */, - C3A5CCF52DFB8FFC004708FF /* README.md */, - ); - path = ExampleLLM; - sourceTree = ""; - }; - C3288D742B6D9313009FF608 /* LinearModelTraining */ = { - isa = PBXGroup; - children = ( - C3288D752B6D9313009FF608 /* LinearModelTraining.swift */, - C3288D842B6D94BD009FF608 /* README.md */, - ); - path = LinearModelTraining; - sourceTree = ""; - }; - C34E48F32B696F0B00FCB841 /* llm-tool */ = { - isa = PBXGroup; - children = ( - C34E48F92B69930300FCB841 /* README.md */, - C34E48F42B696F0B00FCB841 /* LLMTool.swift */, - C36BEFB32BBDEA69002D4AFE /* LoraCommands.swift */, - C36BEFB62BBDECBC002D4AFE /* Arguments.swift */, - C38BA3A92DB8321600BAFA88 /* Chat.swift */, - C37133A12DD6524B00D19830 /* ListCommands.swift */, - ); - path = "llm-tool"; - sourceTree = ""; - }; - C34E49222B6A026F00FCB841 /* mnist-tool */ = { - isa = PBXGroup; - children = ( - C34E49232B6A026F00FCB841 /* MNISTTool.swift */, - C3C3240B2B6CA689007D2D9A /* README.md */, - ); - path = "mnist-tool"; - sourceTree = ""; - }; - C36BEFE12BC32988002D4AFE /* image-tool */ = { - isa = PBXGroup; - children = ( - C36BEFE22BC32988002D4AFE /* ImageTool.swift */, - C36BF0342BC70F11002D4AFE /* Arguments.swift */, - ); - path = "image-tool"; - sourceTree = ""; - }; - C36BF0022BC5CE55002D4AFE /* StableDiffusionExample */ = { - isa = PBXGroup; - children = ( - C3D573052C40701E00857A35 /* README.md */, - C36BF0032BC5CE55002D4AFE /* StableDiffusionExampleApp.swift */, - C36BF0052BC5CE55002D4AFE /* ContentView.swift */, - C36BF0072BC5CE56002D4AFE /* Assets.xcassets */, - C36BF0092BC5CE56002D4AFE /* StableDiffusionExample.entitlements */, - C36BF00A2BC5CE56002D4AFE /* Preview Content */, - ); - path = StableDiffusionExample; - sourceTree = ""; - }; - C36BF00A2BC5CE56002D4AFE /* Preview Content */ = { - isa = PBXGroup; - children = ( - C36BF00B2BC5CE56002D4AFE /* Preview Assets.xcassets */, - ); - path = "Preview Content"; - sourceTree = ""; - }; C39273672B60697700368D5D = { isa = PBXGroup; children = ( C325DE3F2B648CDB00628871 /* README.md */, F8D7023A2BB4E223003D7CF5 /* Package.swift */, - C3C36A6C2CA714600099FFA4 /* Configuration */, - C3056BA62BCD973400A31D04 /* Data */, + C314FCF02EF3313B00E5B73A /* Configuration */, + C314FCF62EF3314200E5B73A /* Data */, C397D92E2CD440EF00B87EE2 /* Libraries */, C3C7C4222DB16A02000373CF /* Tests */, - C3A8B3AD2B9294E30002EFB8 /* Applications */, - C39273812B606A7400368D5D /* Tools */, + C314FDA02EF3315A00E5B73A /* Applications */, + C314FD242EF3315100E5B73A /* Tools */, C39273752B606A0A00368D5D /* Products */, C392737E2B606A2C00368D5D /* Frameworks */, ); @@ -603,23 +547,15 @@ C3056BAB2BCD97B700A31D04 /* LoRATrainingExample.app */, C36BEFE02BC32988002D4AFE /* image-tool */, C36BF0012BC5CE55002D4AFE /* StableDiffusionExample.app */, - 0AC74EBB2D136221003C90A7 /* VLMEval.app */, C3208E6E2DB19451006AE6CA /* MLXLMTests.xctest */, 0F5AD7412DB70C0300745C06 /* MLXChatExample.app */, C3132C232DFB2FFB00270E8E /* ExampleLLM */, 0A979CD12E97175800635D67 /* embedder-tool */, + C314FEDB2EF33B2F00E5B73A /* LLMBasic.app */, ); name = Products; sourceTree = ""; }; - C39273762B606A0A00368D5D /* Tutorial */ = { - isa = PBXGroup; - children = ( - C392737C2B606A1D00368D5D /* Tutorial.swift */, - ); - path = Tutorial; - sourceTree = ""; - }; C392737E2B606A2C00368D5D /* Frameworks */ = { isa = PBXGroup; children = ( @@ -631,80 +567,6 @@ name = Frameworks; sourceTree = ""; }; - C39273812B606A7400368D5D /* Tools */ = { - isa = PBXGroup; - children = ( - C3132C2B2DFB301A00270E8E /* ExampleLLM */, - C36BEFE12BC32988002D4AFE /* image-tool */, - C3288D742B6D9313009FF608 /* LinearModelTraining */, - C34E49222B6A026F00FCB841 /* mnist-tool */, - C34E48F32B696F0B00FCB841 /* llm-tool */, - C39273762B606A0A00368D5D /* Tutorial */, - 0A979CD22E97175800635D67 /* embedder-tool */, - ); - path = Tools; - sourceTree = ""; - }; - C3A8B3AD2B9294E30002EFB8 /* Applications */ = { - isa = PBXGroup; - children = ( - C3056BAC2BCD97B700A31D04 /* LoRATrainingExample */, - C36BF0022BC5CE55002D4AFE /* StableDiffusionExample */, - C3A8B3EB2B92A2A90002EFB8 /* LLMEval */, - C3A8B3C12B92951E0002EFB8 /* MNISTTrainer */, - 0AC74ECE2D13622A003C90A7 /* VLMEval */, - 0F5AD7422DB70C0300745C06 /* MLXChatExample */, - ); - path = Applications; - sourceTree = ""; - }; - C3A8B3C12B92951E0002EFB8 /* MNISTTrainer */ = { - isa = PBXGroup; - children = ( - C3A8B3C32B92951E0002EFB8 /* Assets.xcassets */, - C3A8B3C92B92951E0002EFB8 /* ContentView.swift */, - 12305EAE2B9D864400C92FEE /* PredictionView.swift */, - C3A8B3C22B92951E0002EFB8 /* MNISTTrainer-Info.plist */, - C3A8B3C72B92951E0002EFB8 /* MNISTTrainer.entitlements */, - C3A8B3C42B92951E0002EFB8 /* MNISTTrainerApp.swift */, - C3A8B3C52B92951E0002EFB8 /* Preview Content */, - C3A8B3C82B92951E0002EFB8 /* README.md */, - ); - path = MNISTTrainer; - sourceTree = ""; - }; - C3A8B3C52B92951E0002EFB8 /* Preview Content */ = { - isa = PBXGroup; - children = ( - C3A8B3C62B92951E0002EFB8 /* Preview Assets.xcassets */, - ); - path = "Preview Content"; - sourceTree = ""; - }; - C3A8B3EB2B92A2A90002EFB8 /* LLMEval */ = { - isa = PBXGroup; - children = ( - 6C5EF5C92EEA33D900134C83 /* Views */, - 6C5EF5D42EEA33E800134C83 /* Services */, - 6C5EF5A82EEA33B000134C83 /* Models */, - 6C5EF5BE2EEA33CD00134C83 /* ViewModels */, - 6C5EF5DB2EEA35B700134C83 /* AssetCatalog.xcassets */, - C3A8B3F12B92A2A90002EFB8 /* LLMEval.entitlements */, - C3A8B3ED2B92A2A90002EFB8 /* LLMEvalApp.swift */, - C3A8B3F02B92A2A90002EFB8 /* README.md */, - 6C5EF5D72EEA33FA00134C83 /* AppIcon.icon */, - ); - path = LLMEval; - sourceTree = ""; - }; - C3C36A6C2CA714600099FFA4 /* Configuration */ = { - isa = PBXGroup; - children = ( - C3C36A6B2CA714600099FFA4 /* Build.xcconfig */, - ); - path = Configuration; - sourceTree = ""; - }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ @@ -720,9 +582,6 @@ ); dependencies = ( ); - fileSystemSynchronizedGroups = ( - 0A979CD22E97175800635D67 /* embedder-tool */, - ); name = "embedder-tool"; packageProductDependencies = ( 0A979CD82E9717C500635D67 /* ArgumentParser */, @@ -732,27 +591,6 @@ productReference = 0A979CD12E97175800635D67 /* embedder-tool */; productType = "com.apple.product-type.tool"; }; - 0AC74EBA2D136221003C90A7 /* VLMEval */ = { - isa = PBXNativeTarget; - buildConfigurationList = 0AC74EC62D136223003C90A7 /* Build configuration list for PBXNativeTarget "VLMEval" */; - buildPhases = ( - 0AC74EB72D136221003C90A7 /* Sources */, - 0AC74EB82D136221003C90A7 /* Frameworks */, - 0AC74EB92D136221003C90A7 /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = VLMEval; - packageProductDependencies = ( - 0AC74ED92D136223003C90A7 /* MLXVLM */, - C32B4C6C2DA7136000EF663D /* AsyncAlgorithms */, - ); - productName = VLMEval; - productReference = 0AC74EBB2D136221003C90A7 /* VLMEval.app */; - productType = "com.apple.product-type.application"; - }; 0F5AD7402DB70C0300745C06 /* MLXChatExample */ = { isa = PBXNativeTarget; buildConfigurationList = 0F5AD74C2DB70C0400745C06 /* Build configuration list for PBXNativeTarget "MLXChatExample" */; @@ -765,9 +603,6 @@ ); dependencies = ( ); - fileSystemSynchronizedGroups = ( - 0F5AD7422DB70C0300745C06 /* MLXChatExample */, - ); name = MLXChatExample; packageProductDependencies = ( C32A17FC2CFFB98A0092A5B6 /* MLXLLM */, @@ -790,6 +625,9 @@ ); dependencies = ( ); + fileSystemSynchronizedGroups = ( + C314FCF62EF3314200E5B73A /* Data */, + ); name = LoRATrainingExample; packageProductDependencies = ( C32A18062CFFD1AA0092A5B6 /* MLXLLM */, @@ -819,6 +657,26 @@ productReference = C3132C232DFB2FFB00270E8E /* ExampleLLM */; productType = "com.apple.product-type.tool"; }; + C314FEDA2EF33B2F00E5B73A /* LLMBasic */ = { + isa = PBXNativeTarget; + buildConfigurationList = C314FEE32EF33B3000E5B73A /* Build configuration list for PBXNativeTarget "LLMBasic" */; + buildPhases = ( + C314FED72EF33B2F00E5B73A /* Sources */, + C314FED82EF33B2F00E5B73A /* Frameworks */, + C314FED92EF33B2F00E5B73A /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = LLMBasic; + packageProductDependencies = ( + C314FFE32EF33D0900E5B73A /* MLXLLM */, + ); + productName = LLMBasic; + productReference = C314FEDB2EF33B2F00E5B73A /* LLMBasic.app */; + productType = "com.apple.product-type.application"; + }; C3208E6D2DB19451006AE6CA /* MLXLMTests */ = { isa = PBXNativeTarget; buildConfigurationList = C3208E722DB19451006AE6CA /* Build configuration list for PBXNativeTarget "MLXLMTests" */; @@ -1003,17 +861,10 @@ ); dependencies = ( ); - fileSystemSynchronizedGroups = ( - 6C5EF5A82EEA33B000134C83 /* Models */, - 6C5EF5BE2EEA33CD00134C83 /* ViewModels */, - 6C5EF5C92EEA33D900134C83 /* Views */, - 6C5EF5D42EEA33E800134C83 /* Services */, - ); name = LLMEval; packageProductDependencies = ( 81695B402BA373D300F260D8 /* MarkdownUI */, C32A18042CFFD19F0092A5B6 /* MLXLLM */, - C32B4C6E2DA71ADC00EF663D /* AsyncAlgorithms */, ); productName = LLMEval; productReference = C3A8B3DC2B92A29E0002EFB8 /* LLMEval.app */; @@ -1026,7 +877,7 @@ isa = PBXProject; attributes = { BuildIndependentTargetsInParallel = 1; - LastSwiftUpdateCheck = 2600; + LastSwiftUpdateCheck = 2620; LastUpgradeCheck = 1500; TargetAttributes = { 0A979CD02E97175800635D67 = { @@ -1041,6 +892,9 @@ C3132C222DFB2FFB00270E8E = { CreatedOnToolsVersion = 16.3; }; + C314FEDA2EF33B2F00E5B73A = { + CreatedOnToolsVersion = 26.2; + }; C3288D722B6D9313009FF608 = { CreatedOnToolsVersion = 15.0.1; }; @@ -1083,57 +937,49 @@ C36BEFF02BC32A8C002D4AFE /* XCRemoteSwiftPackageReference "Progress" */, C397D8F22CD2F60B00B87EE2 /* XCLocalSwiftPackageReference "Libraries/.." */, C32A18442D00E13E0092A5B6 /* XCRemoteSwiftPackageReference "mlx-swift" */, - C32B4C6B2DA7132C00EF663D /* XCRemoteSwiftPackageReference "swift-async-algorithms" */, C32AA12E2EB97625002914C6 /* XCRemoteSwiftPackageReference "mlx-swift-lm" */, ); productRefGroup = C39273752B606A0A00368D5D /* Products */; projectDirPath = ""; projectRoot = ""; targets = ( - C39273732B606A0A00368D5D /* Tutorial */, + C3A8B3DB2B92A29D0002EFB8 /* LLMEval */, + 0F5AD7402DB70C0300745C06 /* MLXChatExample */, + C314FEDA2EF33B2F00E5B73A /* LLMBasic */, C397C58A2B62C6A9004B084D /* llm-tool */, - C34E49202B6A026F00FCB841 /* mnist-tool */, + C3132C222DFB2FFB00270E8E /* ExampleLLM */, 0A979CD02E97175800635D67 /* embedder-tool */, - C3288D722B6D9313009FF608 /* LinearModelTraining */, + C36BF0002BC5CE55002D4AFE /* StableDiffusionExample */, C36BEFDF2BC32988002D4AFE /* image-tool */, - C3A8B3DB2B92A29D0002EFB8 /* LLMEval */, - 0AC74EBA2D136221003C90A7 /* VLMEval */, - C3132C222DFB2FFB00270E8E /* ExampleLLM */, - 0F5AD7402DB70C0300745C06 /* MLXChatExample */, - C3A8B3B12B9295090002EFB8 /* MNISTTrainer */, C3056BAA2BCD97B700A31D04 /* LoRATrainingExample */, - C36BF0002BC5CE55002D4AFE /* StableDiffusionExample */, + C34E49202B6A026F00FCB841 /* mnist-tool */, + C3A8B3B12B9295090002EFB8 /* MNISTTrainer */, + C39273732B606A0A00368D5D /* Tutorial */, + C3288D722B6D9313009FF608 /* LinearModelTraining */, C3208E6D2DB19451006AE6CA /* MLXLMTests */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ - 0AC74EB92D136221003C90A7 /* Resources */ = { + 0F5AD73F2DB70C0300745C06 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 0AC74ECF2D13622A003C90A7 /* Preview Assets.xcassets in Resources */, - 0AC74ED02D13622A003C90A7 /* Assets.xcassets in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 0F5AD73F2DB70C0300745C06 /* Resources */ = { + C3056BA92BCD97B700A31D04 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - C3056BA92BCD97B700A31D04 /* Resources */ = { + C314FED92EF33B2F00E5B73A /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - C3056BBA2BCD981900A31D04 /* train.jsonl in Resources */, - C3056BBB2BCD981900A31D04 /* test.jsonl in Resources */, - C3056BBC2BCD981900A31D04 /* valid.jsonl in Resources */, - C3056BB62BCD97B800A31D04 /* Preview Assets.xcassets in Resources */, - C3056BB22BCD97B800A31D04 /* Assets.xcassets in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1148,8 +994,6 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - C36BF00C2BC5CE56002D4AFE /* Preview Assets.xcassets in Resources */, - C36BF0082BC5CE56002D4AFE /* Assets.xcassets in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1157,8 +1001,6 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - C3A8B3CD2B92951E0002EFB8 /* Preview Assets.xcassets in Resources */, - C3A8B3CB2B92951E0002EFB8 /* Assets.xcassets in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1166,8 +1008,6 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 6C5EF5D82EEA33FA00134C83 /* AppIcon.icon in Resources */, - 6C5EF5DC2EEA35B700134C83 /* AssetCatalog.xcassets in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1181,36 +1021,31 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - 0AC74EB72D136221003C90A7 /* Sources */ = { + 0F5AD73D2DB70C0300745C06 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 0AC74ED12D13622A003C90A7 /* ContentView.swift in Sources */, - 0AC74ED22D13622A003C90A7 /* VLMEvalApp.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - 0F5AD73D2DB70C0300745C06 /* Sources */ = { + C3056BA72BCD97B700A31D04 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( ); runOnlyForDeploymentPostprocessing = 0; }; - C3056BA72BCD97B700A31D04 /* Sources */ = { + C3132C1F2DFB2FFB00270E8E /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - C3056BB02BCD97B700A31D04 /* ContentView.swift in Sources */, - C3056BAE2BCD97B700A31D04 /* LoRATrainingExampleApp.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; - C3132C1F2DFB2FFB00270E8E /* Sources */ = { + C314FED72EF33B2F00E5B73A /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - C3132C2C2DFB301A00270E8E /* main.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1225,7 +1060,6 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - C3288D762B6D9313009FF608 /* LinearModelTraining.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1233,7 +1067,6 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - C34E49242B6A026F00FCB841 /* MNISTTool.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1241,8 +1074,6 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - C36BF0352BC70F11002D4AFE /* Arguments.swift in Sources */, - C36BEFE32BC32988002D4AFE /* ImageTool.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1250,8 +1081,6 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - C36BF0062BC5CE55002D4AFE /* ContentView.swift in Sources */, - C36BF0042BC5CE55002D4AFE /* StableDiffusionExampleApp.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1259,7 +1088,6 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - C392737D2B606A1D00368D5D /* Tutorial.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1267,11 +1095,6 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - C36BEFB82BBDED51002D4AFE /* Arguments.swift in Sources */, - C38BA3AA2DB8321600BAFA88 /* Chat.swift in Sources */, - C34E48F52B696F0B00FCB841 /* LLMTool.swift in Sources */, - C36BEFB52BBDEAD8002D4AFE /* LoraCommands.swift in Sources */, - C37133A22DD6524B00D19830 /* ListCommands.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1279,9 +1102,6 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 12305EAF2B9D864400C92FEE /* PredictionView.swift in Sources */, - C3A8B3CC2B92951E0002EFB8 /* MNISTTrainerApp.swift in Sources */, - C3A8B3CF2B92951E0002EFB8 /* ContentView.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1289,7 +1109,6 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - C3A8B3F42B92A2A90002EFB8 /* LLMEvalApp.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1376,133 +1195,6 @@ }; name = Release; }; - 0AC74EC72D136223003C90A7 /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CODE_SIGN_ENTITLEMENTS = Applications/VLMEval/VLMEval.entitlements; - CODE_SIGN_STYLE = Automatic; - COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1; - DEBUG_INFORMATION_FORMAT = dwarf; - DEVELOPMENT_ASSET_PATHS = "\"Applications/VLMEval/Preview Content\""; - DEVELOPMENT_TEAM = ""; - ENABLE_PREVIEWS = YES; - ENABLE_USER_SCRIPT_SANDBOXING = YES; - GCC_C_LANGUAGE_STANDARD = gnu17; - GCC_DYNAMIC_NO_PIC = NO; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GENERATE_INFOPLIST_FILE = YES; - INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; - INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; - INFOPLIST_KEY_UILaunchScreen_Generation = YES; - INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; - INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; - IPHONEOS_DEPLOYMENT_TARGET = 17.2; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - LOCALIZATION_PREFERS_STRING_CATALOGS = YES; - MACOSX_DEPLOYMENT_TARGET = 14.2; - MARKETING_VERSION = 1.0; - MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; - MTL_FAST_MATH = YES; - PRODUCT_BUNDLE_IDENTIFIER = "mlx.VLMEval${DISAMBIGUATOR}"; - PRODUCT_NAME = "$(TARGET_NAME)"; - REGISTER_APP_GROUPS = NO; - SDKROOT = iphoneos; - SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx xros xrsimulator"; - SUPPORTS_MACCATALYST = NO; - SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; - SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; - SWIFT_EMIT_LOC_STRINGS = YES; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2,7"; - }; - name = Debug; - }; - 0AC74EC82D136223003C90A7 /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CODE_SIGN_ENTITLEMENTS = Applications/VLMEval/VLMEval.entitlements; - CODE_SIGN_STYLE = Automatic; - COPY_PHASE_STRIP = NO; - CURRENT_PROJECT_VERSION = 1; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - DEVELOPMENT_ASSET_PATHS = "\"Applications/VLMEval/Preview Content\""; - DEVELOPMENT_TEAM = ""; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_PREVIEWS = YES; - ENABLE_USER_SCRIPT_SANDBOXING = YES; - GCC_C_LANGUAGE_STANDARD = gnu17; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GENERATE_INFOPLIST_FILE = YES; - INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; - INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; - INFOPLIST_KEY_UILaunchScreen_Generation = YES; - INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; - INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; - IPHONEOS_DEPLOYMENT_TARGET = 17.2; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - LOCALIZATION_PREFERS_STRING_CATALOGS = YES; - MACOSX_DEPLOYMENT_TARGET = 14.2; - MARKETING_VERSION = 1.0; - MTL_ENABLE_DEBUG_INFO = NO; - MTL_FAST_MATH = YES; - PRODUCT_BUNDLE_IDENTIFIER = "mlx.VLMEval${DISAMBIGUATOR}"; - PRODUCT_NAME = "$(TARGET_NAME)"; - REGISTER_APP_GROUPS = NO; - SDKROOT = iphoneos; - SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx xros xrsimulator"; - SUPPORTS_MACCATALYST = NO; - SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; - SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; - SWIFT_COMPILATION_MODE = wholemodule; - SWIFT_EMIT_LOC_STRINGS = YES; - SWIFT_VERSION = 5.0; - TARGETED_DEVICE_FAMILY = "1,2,7"; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; 0F5AD74D2DB70C0400745C06 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -1887,6 +1579,166 @@ }; name = Release; }; + C314FEE42EF33B3000E5B73A /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_ENTITLEMENTS = Applications/LLMBasic/LLMBasic.entitlements; + CODE_SIGN_STYLE = Automatic; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + DEVELOPMENT_TEAM = ""; + ENABLE_APP_SANDBOX = YES; + ENABLE_FILE_ACCESS_DOWNLOADS_FOLDER = readwrite; + ENABLE_INCOMING_NETWORK_CONNECTIONS = NO; + ENABLE_OUTGOING_NETWORK_CONNECTIONS = YES; + ENABLE_PREVIEWS = YES; + ENABLE_RESOURCE_ACCESS_AUDIO_INPUT = NO; + ENABLE_RESOURCE_ACCESS_BLUETOOTH = NO; + ENABLE_RESOURCE_ACCESS_CALENDARS = NO; + ENABLE_RESOURCE_ACCESS_CAMERA = NO; + ENABLE_RESOURCE_ACCESS_CONTACTS = NO; + ENABLE_RESOURCE_ACCESS_LOCATION = NO; + ENABLE_RESOURCE_ACCESS_PRINTING = NO; + ENABLE_RESOURCE_ACCESS_USB = NO; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + ENABLE_USER_SELECTED_FILES = readonly; + GCC_C_LANGUAGE_STANDARD = gnu17; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GENERATE_INFOPLIST_FILE = YES; + "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES; + "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphonesimulator*]" = YES; + "INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphoneos*]" = YES; + "INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphonesimulator*]" = YES; + "INFOPLIST_KEY_UILaunchScreen_Generation[sdk=iphoneos*]" = YES; + "INFOPLIST_KEY_UILaunchScreen_Generation[sdk=iphonesimulator*]" = YES; + "INFOPLIST_KEY_UIStatusBarStyle[sdk=iphoneos*]" = UIStatusBarStyleDefault; + "INFOPLIST_KEY_UIStatusBarStyle[sdk=iphonesimulator*]" = UIStatusBarStyleDefault; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + IPHONEOS_DEPLOYMENT_TARGET = 26.2; + LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks"; + "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks"; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MACOSX_DEPLOYMENT_TARGET = 26.2; + MARKETING_VERSION = 1.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = "mlx.LLMBasic${DISAMBIGUATOR}"; + PRODUCT_NAME = "$(TARGET_NAME)"; + REGISTER_APP_GROUPS = YES; + SDKROOT = auto; + STRING_CATALOG_GENERATE_SYMBOLS = YES; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx xros xrsimulator"; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; + SWIFT_APPROACHABLE_CONCURRENCY = YES; + SWIFT_DEFAULT_ACTOR_ISOLATION = MainActor; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES; + SWIFT_VERSION = 6.0; + TARGETED_DEVICE_FAMILY = "1,2,7"; + XROS_DEPLOYMENT_TARGET = 26.2; + }; + name = Debug; + }; + C314FEE52EF33B3000E5B73A /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_ENTITLEMENTS = Applications/LLMBasic/LLMBasic.entitlements; + CODE_SIGN_STYLE = Automatic; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEVELOPMENT_TEAM = ""; + ENABLE_APP_SANDBOX = YES; + ENABLE_FILE_ACCESS_DOWNLOADS_FOLDER = readwrite; + ENABLE_INCOMING_NETWORK_CONNECTIONS = NO; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_OUTGOING_NETWORK_CONNECTIONS = YES; + ENABLE_PREVIEWS = YES; + ENABLE_RESOURCE_ACCESS_AUDIO_INPUT = NO; + ENABLE_RESOURCE_ACCESS_BLUETOOTH = NO; + ENABLE_RESOURCE_ACCESS_CALENDARS = NO; + ENABLE_RESOURCE_ACCESS_CAMERA = NO; + ENABLE_RESOURCE_ACCESS_CONTACTS = NO; + ENABLE_RESOURCE_ACCESS_LOCATION = NO; + ENABLE_RESOURCE_ACCESS_PRINTING = NO; + ENABLE_RESOURCE_ACCESS_USB = NO; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + ENABLE_USER_SELECTED_FILES = readonly; + GCC_C_LANGUAGE_STANDARD = gnu17; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GENERATE_INFOPLIST_FILE = YES; + "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphoneos*]" = YES; + "INFOPLIST_KEY_UIApplicationSceneManifest_Generation[sdk=iphonesimulator*]" = YES; + "INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphoneos*]" = YES; + "INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents[sdk=iphonesimulator*]" = YES; + "INFOPLIST_KEY_UILaunchScreen_Generation[sdk=iphoneos*]" = YES; + "INFOPLIST_KEY_UILaunchScreen_Generation[sdk=iphonesimulator*]" = YES; + "INFOPLIST_KEY_UIStatusBarStyle[sdk=iphoneos*]" = UIStatusBarStyleDefault; + "INFOPLIST_KEY_UIStatusBarStyle[sdk=iphonesimulator*]" = UIStatusBarStyleDefault; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + IPHONEOS_DEPLOYMENT_TARGET = 26.2; + LD_RUNPATH_SEARCH_PATHS = "@executable_path/Frameworks"; + "LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "@executable_path/../Frameworks"; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MACOSX_DEPLOYMENT_TARGET = 26.2; + MARKETING_VERSION = 1.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = "mlx.LLMBasic${DISAMBIGUATOR}"; + PRODUCT_NAME = "$(TARGET_NAME)"; + REGISTER_APP_GROUPS = YES; + SDKROOT = auto; + STRING_CATALOG_GENERATE_SYMBOLS = YES; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator macosx xros xrsimulator"; + SWIFT_APPROACHABLE_CONCURRENCY = YES; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_DEFAULT_ACTOR_ISOLATION = MainActor; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_UPCOMING_FEATURE_MEMBER_IMPORT_VISIBILITY = YES; + SWIFT_VERSION = 6.0; + TARGETED_DEVICE_FAMILY = "1,2,7"; + XROS_DEPLOYMENT_TARGET = 26.2; + }; + name = Release; + }; C3208E732DB19451006AE6CA /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -2538,7 +2390,8 @@ }; C392736C2B60697700368D5D /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = C3C36A6B2CA714600099FFA4 /* Build.xcconfig */; + baseConfigurationReferenceAnchor = C314FCF02EF3313B00E5B73A /* Configuration */; + baseConfigurationReferenceRelativePath = Build.xcconfig; buildSettings = { ARCHS = "$(ARCHS_STANDARD)"; ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; @@ -2577,7 +2430,8 @@ }; C392736D2B60697700368D5D /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = C3C36A6B2CA714600099FFA4 /* Build.xcconfig */; + baseConfigurationReferenceAnchor = C314FCF02EF3313B00E5B73A /* Configuration */; + baseConfigurationReferenceRelativePath = Build.xcconfig; buildSettings = { ARCHS = "$(ARCHS_STANDARD)"; ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; @@ -2910,6 +2764,7 @@ DEAD_CODE_STRIPPING = YES; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_ASSET_PATHS = "\"Applications/MNISTTrainer/Preview Content\""; + DEVELOPMENT_TEAM = ""; ENABLE_PREVIEWS = YES; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; @@ -3003,6 +2858,7 @@ DEAD_CODE_STRIPPING = YES; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_ASSET_PATHS = "\"Applications/MNISTTrainer/Preview Content\""; + DEVELOPMENT_TEAM = ""; ENABLE_NS_ASSERTIONS = NO; ENABLE_PREVIEWS = YES; ENABLE_STRICT_OBJC_MSGSEND = YES; @@ -3238,15 +3094,6 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - 0AC74EC62D136223003C90A7 /* Build configuration list for PBXNativeTarget "VLMEval" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 0AC74EC72D136223003C90A7 /* Debug */, - 0AC74EC82D136223003C90A7 /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; 0F5AD74C2DB70C0400745C06 /* Build configuration list for PBXNativeTarget "MLXChatExample" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -3274,6 +3121,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + C314FEE32EF33B3000E5B73A /* Build configuration list for PBXNativeTarget "LLMBasic" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C314FEE42EF33B3000E5B73A /* Debug */, + C314FEE52EF33B3000E5B73A /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; C3208E722DB19451006AE6CA /* Build configuration list for PBXNativeTarget "MLXLMTests" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -3387,7 +3243,7 @@ repositoryURL = "https://github.com/ml-explore/mlx-swift"; requirement = { kind = upToNextMajorVersion; - minimumVersion = 0.25.4; + minimumVersion = 0.29.1; }; }; C32AA12E2EB97625002914C6 /* XCRemoteSwiftPackageReference "mlx-swift-lm" */ = { @@ -3398,14 +3254,6 @@ minimumVersion = 2.29.2; }; }; - C32B4C6B2DA7132C00EF663D /* XCRemoteSwiftPackageReference "swift-async-algorithms" */ = { - isa = XCRemoteSwiftPackageReference; - repositoryURL = "https://github.com/apple/swift-async-algorithms.git"; - requirement = { - kind = upToNextMajorVersion; - minimumVersion = 1.0.3; - }; - }; C34E491A2B69C43600FCB841 /* XCRemoteSwiftPackageReference "GzipSwift" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/1024jp/GzipSwift"; @@ -3443,11 +3291,6 @@ package = C397D8F22CD2F60B00B87EE2 /* XCLocalSwiftPackageReference "Libraries/.." */; productName = MLXEmbedders; }; - 0AC74ED92D136223003C90A7 /* MLXVLM */ = { - isa = XCSwiftPackageProductDependency; - package = C397D8F22CD2F60B00B87EE2 /* XCLocalSwiftPackageReference "Libraries/.." */; - productName = MLXVLM; - }; 81695B402BA373D300F260D8 /* MarkdownUI */ = { isa = XCSwiftPackageProductDependency; package = 81695B3F2BA373D300F260D8 /* XCRemoteSwiftPackageReference "swift-markdown-ui" */; @@ -3463,6 +3306,11 @@ package = C397D8F22CD2F60B00B87EE2 /* XCLocalSwiftPackageReference "Libraries/.." */; productName = MLXLLM; }; + C314FFE32EF33D0900E5B73A /* MLXLLM */ = { + isa = XCSwiftPackageProductDependency; + package = C32AA12E2EB97625002914C6 /* XCRemoteSwiftPackageReference "mlx-swift-lm" */; + productName = MLXLLM; + }; C3208E752DB1945D006AE6CA /* MLX */ = { isa = XCSwiftPackageProductDependency; package = C32A18442D00E13E0092A5B6 /* XCRemoteSwiftPackageReference "mlx-swift" */; @@ -3543,16 +3391,6 @@ package = C32AA12E2EB97625002914C6 /* XCRemoteSwiftPackageReference "mlx-swift-lm" */; productName = MLXVLM; }; - C32B4C6C2DA7136000EF663D /* AsyncAlgorithms */ = { - isa = XCSwiftPackageProductDependency; - package = C32B4C6B2DA7132C00EF663D /* XCRemoteSwiftPackageReference "swift-async-algorithms" */; - productName = AsyncAlgorithms; - }; - C32B4C6E2DA71ADC00EF663D /* AsyncAlgorithms */ = { - isa = XCSwiftPackageProductDependency; - package = C32B4C6B2DA7132C00EF663D /* XCRemoteSwiftPackageReference "swift-async-algorithms" */; - productName = AsyncAlgorithms; - }; C34E49282B6A028100FCB841 /* ArgumentParser */ = { isa = XCSwiftPackageProductDependency; package = C392736E2B60699100368D5D /* XCRemoteSwiftPackageReference "swift-argument-parser" */; diff --git a/mlx-swift-examples.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/mlx-swift-examples.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved index f49bb763..b7412286 100644 --- a/mlx-swift-examples.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ b/mlx-swift-examples.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -1,5 +1,5 @@ { - "originHash" : "0dd305f09ba278569849d2b91cb2ef7a95956604f60ef1c3013f0e7b4b61d1a7", + "originHash" : "b63947dc4e7cd2d22b1d663a82e277f552af0e8ad0add299d9dec61ceaf8fed0", "pins" : [ { "identity" : "gzipswift", @@ -55,22 +55,13 @@ "version" : "1.6.2" } }, - { - "identity" : "swift-async-algorithms", - "kind" : "remoteSourceControl", - "location" : "https://github.com/apple/swift-async-algorithms.git", - "state" : { - "revision" : "042e1c4d9d19748c9c228f8d4ebc97bb1e339b0b", - "version" : "1.0.4" - } - }, { "identity" : "swift-cmark", "kind" : "remoteSourceControl", "location" : "https://github.com/swiftlang/swift-cmark", "state" : { - "revision" : "b97d09472e847a416629f026eceae0e2afcfad65", - "version" : "0.7.0" + "revision" : "5d9bdaa4228b381639fff09403e39a04926e2dbe", + "version" : "0.7.1" } }, { @@ -87,8 +78,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/huggingface/swift-jinja.git", "state" : { - "revision" : "c1ef5963ba4a97a589b9c9583ff4ee3352a86d23", - "version" : "2.1.0" + "revision" : "06a511d5adab5a812852ff972e65702a24b8ce30", + "version" : "2.2.0" } }, { @@ -114,8 +105,8 @@ "kind" : "remoteSourceControl", "location" : "https://github.com/huggingface/swift-transformers", "state" : { - "revision" : "94610577e4af9bbc267060af1e25e977604dd796", - "version" : "1.1.1" + "revision" : "deea50c380b07535c81f838d10e1efcc8f9019bb", + "version" : "1.1.5" } } ], diff --git a/mlx-swift-examples.xcodeproj/xcshareddata/xcschemes/VLMEval.xcscheme b/mlx-swift-examples.xcodeproj/xcshareddata/xcschemes/LLMBasic.xcscheme similarity index 83% rename from mlx-swift-examples.xcodeproj/xcshareddata/xcschemes/VLMEval.xcscheme rename to mlx-swift-examples.xcodeproj/xcshareddata/xcschemes/LLMBasic.xcscheme index 92f22a14..ffc6c5f1 100644 --- a/mlx-swift-examples.xcodeproj/xcshareddata/xcschemes/VLMEval.xcscheme +++ b/mlx-swift-examples.xcodeproj/xcshareddata/xcschemes/LLMBasic.xcscheme @@ -1,6 +1,6 @@ @@ -44,9 +44,9 @@ runnableDebuggingMode = "0"> @@ -61,9 +61,9 @@ runnableDebuggingMode = "0"> diff --git a/mlx-swift-examples.xcodeproj/xcshareddata/xcschemes/MLXChatExample.xcscheme b/mlx-swift-examples.xcodeproj/xcshareddata/xcschemes/MLXChatExample.xcscheme new file mode 100644 index 00000000..ca11a1c2 --- /dev/null +++ b/mlx-swift-examples.xcodeproj/xcshareddata/xcschemes/MLXChatExample.xcscheme @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/mlx-swift-examples.xcodeproj/xcshareddata/xcschemes/image-tool.xcscheme b/mlx-swift-examples.xcodeproj/xcshareddata/xcschemes/image-tool.xcscheme new file mode 100644 index 00000000..9f0341d6 --- /dev/null +++ b/mlx-swift-examples.xcodeproj/xcshareddata/xcschemes/image-tool.xcscheme @@ -0,0 +1,79 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + From 046a98e3ebf0c783b0f765cc013c7778b312d9aa Mon Sep 17 00:00:00 2001 From: David Koski Date: Wed, 17 Dec 2025 14:00:44 -0800 Subject: [PATCH 2/2] swift-format --- Applications/LLMBasic/ChatModel.swift | 30 ++++++++++++------------- Applications/LLMBasic/ContentView.swift | 24 ++++++++++---------- Applications/LLMBasic/LLMBasicApp.swift | 12 +++++----- 3 files changed, 33 insertions(+), 33 deletions(-) diff --git a/Applications/LLMBasic/ChatModel.swift b/Applications/LLMBasic/ChatModel.swift index 5c97466a..f657f824 100644 --- a/Applications/LLMBasic/ChatModel.swift +++ b/Applications/LLMBasic/ChatModel.swift @@ -1,8 +1,8 @@ // Copyright © 2025 Apple Inc. -import SwiftUI -import MLXLMCommon import MLXLLM +import MLXLMCommon +import SwiftUI /// which model to load private let modelConfiguration = LLMRegistry.gemma3_1B_qat_4bit @@ -18,13 +18,13 @@ private let generateParameters = GenerateParameters(temperature: 0.5) /// Downloads and loads the weights for the model -- we have one of these in the process @MainActor @Observable public class ModelLoader { - + enum State { case idle case loading(Task) case loaded(ModelContainer) } - + public var progress = 0.0 public var isLoaded: Bool { switch state { @@ -32,9 +32,9 @@ private let generateParameters = GenerateParameters(temperature: 0.5) case .loaded: true } } - + private var state = State.idle - + public func model() async throws -> ModelContainer { switch self.state { case .idle: @@ -48,13 +48,13 @@ private let generateParameters = GenerateParameters(temperature: 0.5) } self.state = .loading(task) let model = try await task.value - + self.state = .loaded(model) return model - + case .loading(let task): return try await task.value - + case .loaded(let model): return model } @@ -63,12 +63,12 @@ private let generateParameters = GenerateParameters(temperature: 0.5) /// View model for the ChatSession @MainActor @Observable public class ChatModel { - + private let session: ChatSession - + /// back and forth conversation between the user and LLM public var messages = [Chat.Message]() - + private var task: Task? public var isBusy: Bool { task != nil @@ -80,14 +80,14 @@ private let generateParameters = GenerateParameters(temperature: 0.5) instructions: instructions, generateParameters: generateParameters) } - + public func cancel() { task?.cancel() } - + public func respond(_ message: String) { guard task == nil else { return } - + self.messages.append(.init(role: .user, content: message)) self.messages.append(.init(role: .assistant, content: "...")) let lastIndex = self.messages.count - 1 diff --git a/Applications/LLMBasic/ContentView.swift b/Applications/LLMBasic/ContentView.swift index e5a51755..9c4966da 100644 --- a/Applications/LLMBasic/ContentView.swift +++ b/Applications/LLMBasic/ContentView.swift @@ -1,36 +1,36 @@ // Copyright © 2025 Apple Inc. -import SwiftUI import MLXLMCommon +import SwiftUI struct ContentView: View { - + /// provided by the application let loader: ModelLoader - + /// once loaded this will hold the chat session @State var session: ChatModel? @State var error: String? - + /// prompt for the LLM (text field) @State var prompt = "" - + @FocusState var promptFocused - + var body: some View { VStack { if let error { Text("Error: \(error)") - + } else if !loader.isLoaded { ProgressView("Loading", value: loader.progress, total: 1) - + } else if let session { // show the chat messages ScrollView(.vertical) { ForEach(session.messages.enumerated(), id: \.offset) { _, message in let bold = message.role == .user - + HStack { Text(message.content) .bold(bold) @@ -38,9 +38,9 @@ struct ContentView: View { } .padding(.bottom, 4) } - + Spacer() - + if session.isBusy { // a stop button -- cmd-. to interrupt HStack { @@ -74,7 +74,7 @@ struct ContentView: View { self.session?.cancel() } } - + private func respond() { session?.respond(prompt) prompt = "" diff --git a/Applications/LLMBasic/LLMBasicApp.swift b/Applications/LLMBasic/LLMBasicApp.swift index a514eec0..b3b6d46a 100644 --- a/Applications/LLMBasic/LLMBasicApp.swift +++ b/Applications/LLMBasic/LLMBasicApp.swift @@ -1,19 +1,19 @@ // Copyright © 2025 Apple Inc. -import SwiftUI -import MLXLMCommon -import MLXLLM import MLX +import MLXLLM +import MLXLMCommon +import SwiftUI @main struct LLMBasicApp: App { - + init() { MLX.GPU.set(cacheLimit: 20 * 1024 * 1024) } - + @State var loader = ModelLoader() - + var body: some Scene { WindowGroup { ContentView(loader: loader)