@@ -80,6 +80,25 @@ struct ContentView: View {
80
80
case tokenizer
81
81
}
82
82
83
+ enum ModelType {
84
+ case llama
85
+ case llava
86
+ case qwen3
87
+
88
+ static func fromPath( _ path: String ) -> ModelType {
89
+ let filename = ( path as NSString ) . lastPathComponent. lowercased ( )
90
+ if filename. hasPrefix ( " llama " ) {
91
+ return . llama
92
+ } else if filename. hasPrefix ( " llava " ) {
93
+ return . llava
94
+ } else if filename. hasPrefix ( " qwen3 " ) {
95
+ return . qwen3
96
+ }
97
+ print ( " Unknown model type in path: \( path) . Model filename should start with one of: llama, llava, or qwen3 " )
98
+ exit ( 1 )
99
+ }
100
+ }
101
+
83
102
private var placeholder : String {
84
103
resourceManager. isModelValid ? resourceManager. isTokenizerValid ? " Prompt... " : " Select Tokenizer... " : " Select Model... "
85
104
}
@@ -275,14 +294,14 @@ struct ContentView: View {
275
294
let seq_len = 768 // text: 256, vision: 768
276
295
let modelPath = resourceManager. modelPath
277
296
let tokenizerPath = resourceManager. tokenizerPath
278
- let useLlama = modelPath . lowercased ( ) . contains ( " llama " )
297
+ let modelType = ModelType . fromPath ( modelPath )
279
298
280
299
prompt = " "
281
300
hideKeyboard ( )
282
301
showingSettings = false
283
302
284
303
messages. append ( Message ( text: text) )
285
- messages. append ( Message ( type: useLlama ? . llamagenerated : . llavagenerated) )
304
+ messages. append ( Message ( type: modelType == . llama ? . llamagenerated : . llavagenerated) )
286
305
287
306
runnerQueue. async {
288
307
defer {
@@ -292,14 +311,16 @@ struct ContentView: View {
292
311
}
293
312
}
294
313
295
- if useLlama {
314
+ switch modelType {
315
+ case . llama, . qwen3:
296
316
runnerHolder. runner = runnerHolder. runner ?? Runner ( modelPath: modelPath, tokenizerPath: tokenizerPath)
297
- } else {
317
+ case . llava :
298
318
runnerHolder. llavaRunner = runnerHolder. llavaRunner ?? LLaVARunner ( modelPath: modelPath, tokenizerPath: tokenizerPath)
299
319
}
300
320
301
321
guard !shouldStopGenerating else { return }
302
- if useLlama {
322
+ switch modelType {
323
+ case . llama, . qwen3:
303
324
if let runner = runnerHolder. runner, !runner. isLoaded ( ) {
304
325
var error : Error ?
305
326
let startLoadTime = Date ( )
@@ -329,7 +350,7 @@ struct ContentView: View {
329
350
return
330
351
}
331
352
}
332
- } else {
353
+ case . llava :
333
354
if let runner = runnerHolder. llavaRunner, !runner. isLoaded ( ) {
334
355
var error : Error ?
335
356
let startLoadTime = Date ( )
@@ -411,12 +432,19 @@ struct ContentView: View {
411
432
}
412
433
}
413
434
} else {
414
- let llama3_prompt = " <|begin_of_text|><|start_header_id|>user<|end_header_id|> \( text) <|eot_id|><|start_header_id|>assistant<|end_header_id|> "
435
+ let prompt : String
436
+ switch modelType {
437
+ case . qwen3:
438
+ prompt = String ( format: Constants . qwen3PromptTemplate, text)
439
+ case . llama:
440
+ prompt = String ( format: Constants . llama3PromptTemplate, text)
441
+ case . llava:
442
+ prompt = String ( format: Constants . llama3PromptTemplate, text)
443
+ }
415
444
416
- try runnerHolder. runner? . generate ( llama3_prompt , sequenceLength: seq_len) { token in
445
+ try runnerHolder. runner? . generate ( prompt , sequenceLength: seq_len) { token in
417
446
418
- NSLog ( " >>> token={ \( token) } " )
419
- if token != llama3_prompt {
447
+ if token != prompt {
420
448
// hack to fix the issue that extension/llm/runner/text_token_generator.h
421
449
// keeps generating after <|eot_id|>
422
450
if token == " <|eot_id|> " {
0 commit comments