@@ -67,17 +67,34 @@ private func create<C: Codable, P>(
67
67
/// Typically called via ``LLMModelFactory/load(hub:configuration:progressHandler:)``.
68
68
public class ModelTypeRegistry : @unchecked Sendable {
69
69
70
+ /// Creates an empty registry.
71
+ public init ( ) {
72
+ self . creators = [ : ]
73
+ }
74
+
75
+ /// Creates a registry with given creators.
76
+ public init ( creators: [ String : @Sendable ( URL) throws -> any LanguageModel ] ) {
77
+ self . creators = creators
78
+ }
79
+
80
+ /// Shared instance with default model types.
81
+ public static let shared : ModelTypeRegistry = . init( creators: all ( ) )
82
+
83
+ /// All predefined model types
84
+ private static func all( ) -> [ String : @Sendable ( URL) throws -> any LanguageModel ] {
85
+ [
86
+ " paligemma " : create ( PaliGemmaConfiguration . self, PaliGemma . init) ,
87
+ " qwen2_vl " : create ( Qwen2VLConfiguration . self, Qwen2VL . init) ,
88
+ " idefics3 " : create ( Idefics3Configuration . self, Idefics3 . init) ,
89
+ ]
90
+ }
91
+
70
92
// Note: using NSLock as we have very small (just dictionary get/set)
71
93
// critical sections and expect no contention. this allows the methods
72
94
// to remain synchronous.
73
95
private let lock = NSLock ( )
74
96
75
- private var creators : [ String : @Sendable ( URL) throws -> any LanguageModel ] = [
76
- " paligemma " : create ( PaliGemmaConfiguration . self, PaliGemma . init) ,
77
- " qwen2_vl " : create ( Qwen2VLConfiguration . self, Qwen2VL . init) ,
78
- " qwen2_5_vl " : create ( Qwen25VLConfiguration . self, Qwen25VL . init) ,
79
- " idefics3 " : create ( Idefics3Configuration . self, Idefics3 . init) ,
80
- ]
97
+ private var creators : [ String : @Sendable ( URL) throws -> any LanguageModel ]
81
98
82
99
/// Add a new model to the type registry.
83
100
public func registerModelType(
@@ -105,13 +122,25 @@ public class ModelTypeRegistry: @unchecked Sendable {
105
122
106
123
public class ProcessorTypeRegistry : @unchecked Sendable {
107
124
108
- // Note: using NSLock as we have very small (just dictionary get/set)
109
- // critical sections and expect no contention. this allows the methods
110
- // to remain synchronous.
111
- private let lock = NSLock ( )
125
+ /// Creates an empty registry.
126
+ public init ( ) {
127
+ self . creators = [ : ]
128
+ }
112
129
113
- private var creators :
114
- [ String : @Sendable ( URL , any Tokenizer ) throws -> any UserInputProcessor ] = [
130
+ /// Creates a registry with given creators.
131
+ public init ( creators: [ String : @Sendable ( URL , any Tokenizer ) throws -> any UserInputProcessor ] )
132
+ {
133
+ self . creators = creators
134
+ }
135
+
136
+ /// Shared instance with default processor types.
137
+ public static let shared : ProcessorTypeRegistry = . init( creators: all ( ) )
138
+
139
+ /// All predefined processor types.
140
+ private static func all( ) -> [ String : @Sendable ( URL , any Tokenizer ) throws ->
141
+ any UserInputProcessor ]
142
+ {
143
+ [
115
144
" PaliGemmaProcessor " : create (
116
145
PaliGemmaProcessorConfiguration . self, PaliGemmaProcessor . init) ,
117
146
" Qwen2VLProcessor " : create (
@@ -121,6 +150,14 @@ public class ProcessorTypeRegistry: @unchecked Sendable {
121
150
" Idefics3Processor " : create (
122
151
Idefics3ProcessorConfiguration . self, Idefics3Processor . init) ,
123
152
]
153
+ }
154
+
155
+ // Note: using NSLock as we have very small (just dictionary get/set)
156
+ // critical sections and expect no contention. this allows the methods
157
+ // to remain synchronous.
158
+ private let lock = NSLock ( )
159
+
160
+ private var creators : [ String : @Sendable ( URL , any Tokenizer ) throws -> any UserInputProcessor ]
124
161
125
162
/// Add a new model to the type registry.
126
163
public func registerProcessorType(
@@ -156,12 +193,21 @@ public class ProcessorTypeRegistry: @unchecked Sendable {
156
193
/// swift-tokenizers code handles a good chunk of that and this is a place to augment that
157
194
/// implementation, if needed.
158
195
public class ModelRegistry : @unchecked Sendable {
196
+ /// Creates an empty registry.
197
+ public init ( ) {
198
+ registry = Dictionary ( )
199
+ }
200
+
201
+ /// Creates a new registry with from given model configurations.
202
+ public init ( modelConfigurations: [ ModelConfiguration ] ) {
203
+ registry = Dictionary ( uniqueKeysWithValues: modelConfigurations. map { ( $0. name, $0) } )
204
+ }
205
+
206
+ /// Shared instance with default model configurations.
207
+ public static let shared = ModelRegistry ( modelConfigurations: all ( ) )
159
208
160
209
private let lock = NSLock ( )
161
- private var registry = Dictionary (
162
- uniqueKeysWithValues: all ( ) . map {
163
- ( $0. name, $0)
164
- } )
210
+ private var registry : [ String : ModelConfiguration ]
165
211
166
212
static public let paligemma3bMix448_8bit = ModelConfiguration (
167
213
id: " mlx-community/paligemma-3b-mix-448-8bit " ,
@@ -188,6 +234,7 @@ public class ModelRegistry: @unchecked Sendable {
188
234
paligemma3bMix448_8bit,
189
235
qwen2VL2BInstruct4Bit,
190
236
qwen2_5VL3BInstruct4Bit,
237
+ smolvlminstruct4bit,
191
238
]
192
239
}
193
240
@@ -208,6 +255,12 @@ public class ModelRegistry: @unchecked Sendable {
208
255
}
209
256
}
210
257
}
258
+
259
+ public var models : some Collection < ModelConfiguration > & Sendable {
260
+ lock. withLock {
261
+ return registry. values
262
+ }
263
+ }
211
264
}
212
265
213
266
/// Factory for creating new LLMs.
@@ -221,16 +274,27 @@ public class ModelRegistry: @unchecked Sendable {
221
274
/// ```
222
275
public class VLMModelFactory : ModelFactory {
223
276
224
- public static let shared = VLMModelFactory ( )
277
+ public init (
278
+ typeRegistry: ModelTypeRegistry , processorRegistry: ProcessorTypeRegistry ,
279
+ modelRegistry: ModelRegistry
280
+ ) {
281
+ self . typeRegistry = typeRegistry
282
+ self . processorRegistry = processorRegistry
283
+ self . modelRegistry = modelRegistry
284
+ }
285
+
286
+ /// Shared instance with default behavior.
287
+ public static let shared = VLMModelFactory (
288
+ typeRegistry: . shared, processorRegistry: . shared, modelRegistry: . shared)
225
289
226
290
/// registry of model type, e.g. configuration value `paligemma` -> configuration and init methods
227
- public let typeRegistry = ModelTypeRegistry ( )
291
+ public let typeRegistry : ModelTypeRegistry
228
292
229
293
/// registry of input processor type, e.g. configuration value `PaliGemmaProcessor` -> configuration and init methods
230
- public let processorRegistry = ProcessorTypeRegistry ( )
294
+ public let processorRegistry : ProcessorTypeRegistry
231
295
232
296
/// registry of model id to configuration, e.g. `mlx-community/paligemma-3b-mix-448-8bit`
233
- public let modelRegistry = ModelRegistry ( )
297
+ public let modelRegistry : ModelRegistry
234
298
235
299
public func configuration( id: String ) -> ModelConfiguration {
236
300
modelRegistry. configuration ( id: id)
0 commit comments