@@ -52,16 +52,34 @@ private func create<C: Codable, P>(
52
52
/// Typically called via ``LLMModelFactory/load(hub:configuration:progressHandler:)``.
53
53
public class ModelTypeRegistry : @unchecked Sendable {
54
54
55
+ /// Creates an empty registry.
56
+ public init ( ) {
57
+ self . creators = [ : ]
58
+ }
59
+
60
+ /// Creates a registry with given creators.
61
+ public init ( creators: [ String : @Sendable ( URL) throws -> any LanguageModel ] ) {
62
+ self . creators = creators
63
+ }
64
+
65
+ /// Shared instance with default model types.
66
+ public static let shared : ModelTypeRegistry = . init( creators: all ( ) )
67
+
68
+ /// All predefined model types
69
+ private static func all( ) -> [ String : @Sendable ( URL) throws -> any LanguageModel ] {
70
+ [
71
+ " paligemma " : create ( PaliGemmaConfiguration . self, PaliGemma . init) ,
72
+ " qwen2_vl " : create ( Qwen2VLConfiguration . self, Qwen2VL . init) ,
73
+ " idefics3 " : create ( Idefics3Configuration . self, Idefics3 . init) ,
74
+ ]
75
+ }
76
+
55
77
// Note: using NSLock as we have very small (just dictionary get/set)
56
78
// critical sections and expect no contention. this allows the methods
57
79
// to remain synchronous.
58
80
private let lock = NSLock ( )
59
81
60
- private var creators : [ String : @Sendable ( URL) throws -> any LanguageModel ] = [
61
- " paligemma " : create ( PaliGemmaConfiguration . self, PaliGemma . init) ,
62
- " qwen2_vl " : create ( Qwen2VLConfiguration . self, Qwen2VL . init) ,
63
- " idefics3 " : create ( Idefics3Configuration . self, Idefics3 . init) ,
64
- ]
82
+ private var creators : [ String : @Sendable ( URL) throws -> any LanguageModel ]
65
83
66
84
/// Add a new model to the type registry.
67
85
public func registerModelType(
@@ -90,20 +108,39 @@ public class ModelTypeRegistry: @unchecked Sendable {
90
108
91
109
public class ProcessorTypeRegistry : @unchecked Sendable {
92
110
93
- // Note: using NSLock as we have very small (just dictionary get/set)
94
- // critical sections and expect no contention. this allows the methods
95
- // to remain synchronous.
96
- private let lock = NSLock ( )
111
+ /// Creates an empty registry.
112
+ public init ( ) {
113
+ self . creators = [ : ]
114
+ }
115
+
116
+ /// Creates a registry with given creators.
117
+ public init ( creators: [ String : @Sendable ( URL , any Tokenizer ) throws -> any UserInputProcessor ] )
118
+ {
119
+ self . creators = creators
120
+ }
97
121
98
- private var creators :
99
- [ String : @Sendable ( URL , any Tokenizer ) throws -> any UserInputProcessor ] = [
122
+ /// Shared instance with default processor types.
123
+ public static let shared : ProcessorTypeRegistry = . init( creators: all ( ) )
124
+
125
+ /// All predefined processor types.
126
+ private static func all( ) -> [ String : @Sendable ( URL , any Tokenizer ) throws ->
127
+ any UserInputProcessor ]
128
+ {
129
+ [
100
130
" PaliGemmaProcessor " : create (
101
131
PaliGemmaProcessorConfiguration . self, PaligGemmaProcessor . init) ,
102
- " Qwen2VLProcessor " : create (
103
- Qwen2VLProcessorConfiguration . self, Qwen2VLProcessor . init) ,
132
+ " Qwen2VLProcessor " : create ( Qwen2VLProcessorConfiguration . self, Qwen2VLProcessor . init) ,
104
133
" Idefics3Processor " : create (
105
134
Idefics3ProcessorConfiguration . self, Idefics3Processor . init) ,
106
135
]
136
+ }
137
+
138
+ // Note: using NSLock as we have very small (just dictionary get/set)
139
+ // critical sections and expect no contention. this allows the methods
140
+ // to remain synchronous.
141
+ private let lock = NSLock ( )
142
+
143
+ private var creators : [ String : @Sendable ( URL , any Tokenizer ) throws -> any UserInputProcessor ]
107
144
108
145
/// Add a new model to the type registry.
109
146
public func registerProcessorType(
@@ -140,12 +177,21 @@ public class ProcessorTypeRegistry: @unchecked Sendable {
140
177
/// swift-tokenizers code handles a good chunk of that and this is a place to augment that
141
178
/// implementation, if needed.
142
179
public class ModelRegistry : @unchecked Sendable {
180
+ /// Creates an empty registry.
181
+ public init ( ) {
182
+ registry = Dictionary ( )
183
+ }
184
+
185
+ /// Creates a new registry with from given model configurations.
186
+ public init ( modelConfigurations: [ ModelConfiguration ] ) {
187
+ registry = Dictionary ( uniqueKeysWithValues: modelConfigurations. map { ( $0. name, $0) } )
188
+ }
189
+
190
+ /// Shared instance with default model configurations.
191
+ public static let shared = ModelRegistry ( modelConfigurations: all ( ) )
143
192
144
193
private let lock = NSLock ( )
145
- private var registry = Dictionary (
146
- uniqueKeysWithValues: all ( ) . map {
147
- ( $0. name, $0)
148
- } )
194
+ private var registry : [ String : ModelConfiguration ]
149
195
150
196
static public let paligemma3bMix448_8bit = ModelConfiguration (
151
197
id: " mlx-community/paligemma-3b-mix-448-8bit " ,
@@ -166,6 +212,7 @@ public class ModelRegistry: @unchecked Sendable {
166
212
[
167
213
paligemma3bMix448_8bit,
168
214
qwen2VL2BInstruct4Bit,
215
+ smolvlminstruct4bit,
169
216
]
170
217
}
171
218
@@ -205,16 +252,27 @@ public class ModelRegistry: @unchecked Sendable {
205
252
/// ```
206
253
public class VLMModelFactory : ModelFactory {
207
254
208
- public static let shared = VLMModelFactory ( )
255
+ public init (
256
+ typeRegistry: ModelTypeRegistry , processorRegistry: ProcessorTypeRegistry ,
257
+ modelRegistry: ModelRegistry
258
+ ) {
259
+ self . typeRegistry = typeRegistry
260
+ self . processorRegistry = processorRegistry
261
+ self . modelRegistry = modelRegistry
262
+ }
263
+
264
+ /// Shared instance with default behavior.
265
+ public static let shared = VLMModelFactory (
266
+ typeRegistry: . shared, processorRegistry: . shared, modelRegistry: . shared)
209
267
210
268
/// registry of model type, e.g. configuration value `paligemma` -> configuration and init methods
211
- public let typeRegistry = ModelTypeRegistry ( )
269
+ public let typeRegistry : ModelTypeRegistry
212
270
213
271
/// registry of input processor type, e.g. configuration value `PaliGemmaProcessor` -> configuration and init methods
214
- public let processorRegistry = ProcessorTypeRegistry ( )
272
+ public let processorRegistry : ProcessorTypeRegistry
215
273
216
274
/// registry of model id to configuration, e.g. `mlx-community/paligemma-3b-mix-448-8bit`
217
- public let modelRegistry = ModelRegistry ( )
275
+ public let modelRegistry : ModelRegistry
218
276
219
277
public func configuration( id: String ) -> ModelConfiguration {
220
278
modelRegistry. configuration ( id: id)
0 commit comments