diff --git a/.gitignore b/.gitignore index 330d167..a4fa37d 100644 --- a/.gitignore +++ b/.gitignore @@ -37,14 +37,14 @@ playground.xcworkspace # Swift Package Manager # # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. -# Packages/ -# Package.pins -# Package.resolved +Packages/ +Package.pins +Package.resolved # *.xcodeproj # # Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata # hence it is not needed unless you have added a package configuration file to your project -# .swiftpm +.swiftpm .build/ @@ -88,3 +88,7 @@ fastlane/test_output # https://github.com/johnno1962/injectionforxcode iOSInjectionProject/ + +# OS +.DS_Store + diff --git a/Libraries/LLM/Configuration.swift b/Libraries/LLM/Configuration.swift index d1fdedc..f29151f 100644 --- a/Libraries/LLM/Configuration.swift +++ b/Libraries/LLM/Configuration.swift @@ -35,7 +35,7 @@ public enum ModelType: String, Codable { case starcoder2 case cohere - func createModel(configuration: URL) throws -> LLMModel { + public func createModel(configuration: URL) throws -> LLMModel { switch self { case .mistral, .llama: let configuration = try JSONDecoder().decode( @@ -66,7 +66,7 @@ public enum ModelType: String, Codable { } public struct BaseConfiguration: Codable { - let modelType: ModelType + public let modelType: ModelType public struct Quantization: Codable { public init(groupSize: Int, bits: Int) { @@ -83,7 +83,7 @@ public struct BaseConfiguration: Codable { } } - var quantization: Quantization? + public var quantization: Quantization? enum CodingKeys: String, CodingKey { case modelType = "model_type" diff --git a/Package.resolved b/Package.resolved new file mode 100644 index 0000000..1e2f6dc --- /dev/null +++ b/Package.resolved @@ -0,0 +1,68 @@ +{ + "pins" : [ + { + "identity" : "gzipswift", + "kind" : "remoteSourceControl", + "location" : "https://github.com/1024jp/GzipSwift", + "state" : { + "revision" : "731037f6cc2be2ec01562f6597c1d0aa3fe6fd05", + "version" : "6.0.1" + } + }, + { + "identity" : "mlx-swift", + "kind" : "remoteSourceControl", + "location" : "https://github.com/ml-explore/mlx-swift", + "state" : { + "branch" : "main", + "revision" : "5e51224ac869366017859dc0b07f6d2dc51b3bae" + } + }, + { + "identity" : "swift-argument-parser", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-argument-parser.git", + "state" : { + "revision" : "c8ed701b513cf5177118a175d85fbbbcd707ab41", + "version" : "1.3.0" + } + }, + { + "identity" : "swift-async-algorithms", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-async-algorithms", + "state" : { + "revision" : "da4e36f86544cdf733a40d59b3a2267e3a7bbf36", + "version" : "1.0.0" + } + }, + { + "identity" : "swift-collections", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-collections.git", + "state" : { + "revision" : "94cf62b3ba8d4bed62680a282d4c25f9c63c2efb", + "version" : "1.1.0" + } + }, + { + "identity" : "swift-numerics", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-numerics", + "state" : { + "revision" : "0a5bc04095a675662cf24757cc0640aa2204253b", + "version" : "1.0.2" + } + }, + { + "identity" : "swift-transformers", + "kind" : "remoteSourceControl", + "location" : "https://github.com/huggingface/swift-transformers", + "state" : { + "revision" : "4f915610451d29a05948802a140880ff37494dad", + "version" : "0.1.6" + } + } + ], + "version" : 2 +} diff --git a/Package.swift b/Package.swift new file mode 100644 index 0000000..0a12b72 --- /dev/null +++ b/Package.swift @@ -0,0 +1,58 @@ +// swift-tools-version: 5.9 +// The swift-tools-version declares the minimum version of Swift required to build this package. + +import PackageDescription + +let package = Package( + name: "mlx-libraries", + platforms: [.macOS(.v14), .iOS(.v16)], + products: [ + .library( + name: "LLM", + targets: ["MLXLLM"]), + .library( + name: "MNIST", + targets: ["MLXMNIST"]), + ], + dependencies: [ + .package(url: "https://github.com/ml-explore/mlx-swift", branch: "main"), + .package(url: "https://github.com/huggingface/swift-transformers", from: "0.1.5"), + .package(url: "https://github.com/1024jp/GzipSwift", from: "6.0.1"), + .package(url: "https://github.com/apple/swift-async-algorithms", from: "1.0.0"), + ], + targets: [ + .target( + name: "MLXLLM", + dependencies: [ + .product(name: "MLX", package: "mlx-swift"), + .product(name: "MLXFast", package: "mlx-swift"), + .product(name: "MLXNN", package: "mlx-swift"), + .product(name: "MLXRandom", package: "mlx-swift"), + .product(name: "Transformers", package: "swift-transformers"), + .product(name: "AsyncAlgorithms", package: "swift-async-algorithms"), + ], + path: "Libraries/LLM", + exclude: [ + "README.md", + "LLM.h", + ] + ), + .target( + name: "MLXMNIST", + dependencies: [ + .product(name: "MLX", package: "mlx-swift"), + .product(name: "MLXFast", package: "mlx-swift"), + .product(name: "MLXNN", package: "mlx-swift"), + .product(name: "MLXRandom", package: "mlx-swift"), + .product(name: "Transformers", package: "swift-transformers"), + .product(name: "AsyncAlgorithms", package: "swift-async-algorithms"), + .product(name: "Gzip", package: "GzipSwift"), + ], + path: "Libraries/MNIST", + exclude: [ + "README.md", + "MNIST.h", + ] + ), + ] +) diff --git a/README.md b/README.md index 95914f6..7db9971 100644 --- a/README.md +++ b/README.md @@ -18,3 +18,27 @@ Example [MLX Swift](https://github.com/ml-explore/mlx-swift) programs. - [mnist-tool](Tools/mnist-tool/README.md): A command line tool for training a a LeNet on MNIST. + + +## Installation of MLXLLM and MLXMNIST libraries + +The MLXLLM and MLXMNIST libraries in the example repo are available as Swift Packages. + + +Add the following dependency to your Package.swift + +```swift +.package(url: "https://github.com/ml-explore/mlx-swift-examples/", branch: "main"), +``` + +Then add one library or both libraries to the target as a dependency. + +```swift +.target( + name: "YourTargetName", + dependencies: [ + .product(name: "LLM", package: "mlx-swift-examples") + ]), +``` + +Alternatively, add `https://github.com/ml-explore/mlx-swift-examples/` to the `Project Dependencies` and set the `Dependency Rule` to `Branch` and `main` in Xcode. diff --git a/mlx-swift-examples.xcodeproj/project.pbxproj b/mlx-swift-examples.xcodeproj/project.pbxproj index f600a0d..27e0a60 100644 --- a/mlx-swift-examples.xcodeproj/project.pbxproj +++ b/mlx-swift-examples.xcodeproj/project.pbxproj @@ -236,6 +236,7 @@ C3E786AA2B8D1AEC0004D037 /* Evaluate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Evaluate.swift; sourceTree = ""; }; C3E786AC2B8D4AF50004D037 /* Tokenizer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Tokenizer.swift; sourceTree = ""; }; F24B08392BAF1A65008C8D19 /* Cohere.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Cohere.swift; sourceTree = ""; }; + F8D7023A2BB4E223003D7CF5 /* Package.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Package.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -394,6 +395,7 @@ isa = PBXGroup; children = ( C325DE3F2B648CDB00628871 /* README.md */, + F8D7023A2BB4E223003D7CF5 /* Package.swift */, C39273822B606A9200368D5D /* Libraries */, C3A8B3AD2B9294E30002EFB8 /* Applications */, C39273812B606A7400368D5D /* Tools */,