Skip to content

Commit 8dde918

Browse files
authored
Split LLaMA and LLaVA runners.
Differential Revision: D77407510 Pull Request resolved: #12036
1 parent f49cf00 commit 8dde918

File tree

6 files changed

+165
-131
lines changed

6 files changed

+165
-131
lines changed

examples/demo-apps/apple_ios/LLaMA/LLaMA.xcodeproj/project.pbxproj

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,8 @@
4646
03D03DA82C7823620088D6A7 /* text_prefiller.h in Headers */ = {isa = PBXBuildFile; fileRef = 03D03DA62C7823620088D6A7 /* text_prefiller.h */; };
4747
03D03DAB2C7823830088D6A7 /* text_decoder_runner.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 03D03DA92C7823830088D6A7 /* text_decoder_runner.cpp */; };
4848
03D03DAC2C7823830088D6A7 /* text_decoder_runner.h in Headers */ = {isa = PBXBuildFile; fileRef = 03D03DAA2C7823830088D6A7 /* text_decoder_runner.h */; };
49+
03D151B82E0E0908007A38BE /* LLaVARunner.mm in Sources */ = {isa = PBXBuildFile; fileRef = 03D151B72E0E0908007A38BE /* LLaVARunner.mm */; };
50+
03D151B92E0E0908007A38BE /* LLaVARunner.h in Headers */ = {isa = PBXBuildFile; fileRef = 03D151B62E0E0908007A38BE /* LLaVARunner.h */; };
4951
26A6A4282C8A3769005A761E /* ImagePicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 26A6A4272C8A3769005A761E /* ImagePicker.swift */; };
5052
306A713D2DC1DC0F00936B1F /* token_decoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 306A713C2DC1DC0F00936B1F /* token_decoder.h */; };
5153
306A713E2DC1DC0F00936B1F /* regex.h in Headers */ = {isa = PBXBuildFile; fileRef = 306A71392DC1DC0F00936B1F /* regex.h */; };
@@ -132,6 +134,8 @@
132134
03D03DA62C7823620088D6A7 /* text_prefiller.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = text_prefiller.h; sourceTree = "<group>"; };
133135
03D03DA92C7823830088D6A7 /* text_decoder_runner.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = text_decoder_runner.cpp; sourceTree = "<group>"; };
134136
03D03DAA2C7823830088D6A7 /* text_decoder_runner.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = text_decoder_runner.h; sourceTree = "<group>"; };
137+
03D151B62E0E0908007A38BE /* LLaVARunner.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LLaVARunner.h; sourceTree = "<group>"; };
138+
03D151B72E0E0908007A38BE /* LLaVARunner.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = LLaVARunner.mm; sourceTree = "<group>"; };
135139
26A6A4272C8A3769005A761E /* ImagePicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImagePicker.swift; sourceTree = "<group>"; };
136140
306A71352DC1DC0F00936B1F /* hf_tokenizer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = hf_tokenizer.h; sourceTree = "<group>"; };
137141
306A71362DC1DC0F00936B1F /* pcre2_regex.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = pcre2_regex.h; sourceTree = "<group>"; };
@@ -245,6 +249,8 @@
245249
0324D69B2BAACB7C00DEF36F /* Exported */ = {
246250
isa = PBXGroup;
247251
children = (
252+
03D151B62E0E0908007A38BE /* LLaVARunner.h */,
253+
03D151B72E0E0908007A38BE /* LLaVARunner.mm */,
248254
0324D6992BAACB7C00DEF36F /* LLaMARunner.h */,
249255
0324D69A2BAACB7C00DEF36F /* LLaMARunner.mm */,
250256
);
@@ -403,6 +409,7 @@
403409
306A71422DC1DC0F00936B1F /* pre_tokenizer.h in Headers */,
404410
306A71432DC1DC0F00936B1F /* pcre2_regex.h in Headers */,
405411
306A71442DC1DC0F00936B1F /* std_regex.h in Headers */,
412+
03D151B92E0E0908007A38BE /* LLaVARunner.h in Headers */,
406413
03729F122BB2042B00152F2E /* sampler.h in Headers */,
407414
03729F0C2BB203B300152F2E /* util.h in Headers */,
408415
F292B1012D88B20C00BE6839 /* llama_tiktoken.h in Headers */,
@@ -574,6 +581,7 @@
574581
isa = PBXSourcesBuildPhase;
575582
buildActionMask = 2147483647;
576583
files = (
584+
03D151B82E0E0908007A38BE /* LLaVARunner.mm in Sources */,
577585
03729EE12BB1F93800152F2E /* LLaMARunner.mm in Sources */,
578586
0372C3152C89418E00CD942A /* llava_runner.cpp in Sources */,
579587
F292B1022D88B20C00BE6839 /* llama_tiktoken.cpp in Sources */,

examples/demo-apps/apple_ios/LLaMA/LLaMA/Application/ContentView.swift

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import UniformTypeIdentifiers
1212
import LLaMARunner
1313

1414
class RunnerHolder: ObservableObject {
15-
var runner: Runner?
15+
var llamaRunner: LLaMARunner?
1616
var llavaRunner: LLaVARunner?
1717
}
1818

@@ -87,7 +87,7 @@ struct ContentView: View {
8787
case llava
8888
case qwen3
8989
case phi4
90-
90+
9191
static func fromPath(_ path: String) -> ModelType {
9292
let filename = (path as NSString).lastPathComponent.lowercased()
9393
if filename.hasPrefix("llama") {
@@ -347,15 +347,15 @@ struct ContentView: View {
347347

348348
switch modelType {
349349
case .llama, .qwen3, .phi4:
350-
runnerHolder.runner = runnerHolder.runner ?? Runner(modelPath: modelPath, tokenizerPath: tokenizerPath)
350+
runnerHolder.llamaRunner = runnerHolder.llamaRunner ?? LLaMARunner(modelPath: modelPath, tokenizerPath: tokenizerPath)
351351
case .llava:
352352
runnerHolder.llavaRunner = runnerHolder.llavaRunner ?? LLaVARunner(modelPath: modelPath, tokenizerPath: tokenizerPath)
353353
}
354354

355355
guard !shouldStopGenerating else { return }
356356
switch modelType {
357357
case .llama, .qwen3, .phi4:
358-
if let runner = runnerHolder.runner, !runner.isLoaded() {
358+
if let runner = runnerHolder.llamaRunner, !runner.isLoaded() {
359359
var error: Error?
360360
let startLoadTime = Date()
361361
do {
@@ -481,7 +481,7 @@ struct ContentView: View {
481481
prompt = String(format: Constants.phi4PromptTemplate, text)
482482
}
483483

484-
try runnerHolder.runner?.generate(prompt, sequenceLength: seq_len) { token in
484+
try runnerHolder.llamaRunner?.generate(prompt, sequenceLength: seq_len) { token in
485485

486486
if token != prompt {
487487
if token == "<|eot_id|>" {
@@ -534,7 +534,7 @@ struct ContentView: View {
534534
}
535535
}
536536
if shouldStopGenerating {
537-
runnerHolder.runner?.stop()
537+
runnerHolder.llamaRunner?.stop()
538538
}
539539
}
540540
}
@@ -577,7 +577,7 @@ struct ContentView: View {
577577
return
578578
}
579579
runnerQueue.async {
580-
runnerHolder.runner = nil
580+
runnerHolder.llamaRunner = nil
581581
runnerHolder.llavaRunner = nil
582582
}
583583
switch pickerType {

examples/demo-apps/apple_ios/LLaMA/LLaMARunner/LLaMARunner/Exported/LLaMARunner.h

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,7 @@
1111
NS_ASSUME_NONNULL_BEGIN
1212

1313
FOUNDATION_EXPORT NSErrorDomain const LLaMARunnerErrorDomain;
14-
FOUNDATION_EXPORT NSErrorDomain const LLaVARunnerErrorDomain;
1514

16-
NS_SWIFT_NAME(Runner)
1715
@interface LLaMARunner : NSObject
1816

1917
- (instancetype)initWithModelPath:(NSString*)filePath
@@ -31,25 +29,4 @@ NS_SWIFT_NAME(Runner)
3129

3230
@end
3331

34-
NS_SWIFT_NAME(LLaVARunner)
35-
@interface LLaVARunner : NSObject
36-
37-
- (instancetype)initWithModelPath:(NSString*)filePath
38-
tokenizerPath:(NSString*)tokenizerPath;
39-
- (BOOL)isLoaded;
40-
- (BOOL)loadWithError:(NSError**)error;
41-
- (BOOL)generate:(void*)imageBuffer
42-
width:(CGFloat)width
43-
height:(CGFloat)height
44-
prompt:(NSString*)prompt
45-
sequenceLength:(NSInteger)seq_len
46-
withTokenCallback:(nullable void (^)(NSString*))callback
47-
error:(NSError**)error;
48-
- (void)stop;
49-
50-
+ (instancetype)new NS_UNAVAILABLE;
51-
- (instancetype)init NS_UNAVAILABLE;
52-
53-
@end
54-
5532
NS_ASSUME_NONNULL_END

examples/demo-apps/apple_ios/LLaMA/LLaMARunner/LLaMARunner/Exported/LLaMARunner.mm

Lines changed: 0 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,12 @@
1010

1111
#import <ExecuTorch/ExecuTorchLog.h>
1212
#import <executorch/examples/models/llama/runner/runner.h>
13-
#import <executorch/examples/models/llava/runner/llava_runner.h>
1413

1514
using executorch::extension::llm::GenerationConfig;
16-
using executorch::extension::llm::Image;
1715
using executorch::extension::llm::TextLLMRunner;
1816
using executorch::runtime::Error;
1917

2018
NSErrorDomain const LLaMARunnerErrorDomain = @"LLaMARunnerErrorDomain";
21-
NSErrorDomain const LLaVARunnerErrorDomain = @"LLaVARunnerErrorDomain";
2219

2320
@interface LLaMARunner ()<ExecuTorchLogSink>
2421
@end
@@ -110,101 +107,3 @@ - (void)logWithLevel:(ExecuTorchLogLevel)level
110107
}
111108

112109
@end
113-
114-
@interface LLaVARunner ()<ExecuTorchLogSink>
115-
@end
116-
117-
@implementation LLaVARunner {
118-
std::unique_ptr<example::LlavaRunner> _runner;
119-
}
120-
121-
- (instancetype)initWithModelPath:(NSString*)modelPath
122-
tokenizerPath:(NSString*)tokenizerPath {
123-
self = [super init];
124-
if (self) {
125-
[ExecuTorchLog.sharedLog addSink:self];
126-
_runner = std::make_unique<example::LlavaRunner>(
127-
modelPath.UTF8String, tokenizerPath.UTF8String);
128-
}
129-
return self;
130-
}
131-
132-
- (void)dealloc {
133-
[ExecuTorchLog.sharedLog removeSink:self];
134-
}
135-
136-
- (BOOL)isLoaded {
137-
return _runner->is_loaded();
138-
}
139-
140-
- (BOOL)loadWithError:(NSError**)error {
141-
const auto status = _runner->load();
142-
if (status != Error::Ok) {
143-
if (error) {
144-
*error = [NSError errorWithDomain:LLaVARunnerErrorDomain
145-
code:(NSInteger)status
146-
userInfo:nil];
147-
}
148-
return NO;
149-
}
150-
return YES;
151-
}
152-
153-
- (BOOL)generate:(void*)imageBuffer
154-
width:(CGFloat)width
155-
height:(CGFloat)height
156-
prompt:(NSString*)prompt
157-
sequenceLength:(NSInteger)seq_len
158-
withTokenCallback:(nullable void (^)(NSString*))callback
159-
error:(NSError**)error {
160-
const auto* data = static_cast<uint8_t*>(imageBuffer);
161-
const auto status = _runner->generate(
162-
{Image{
163-
std::vector<uint8_t>(
164-
data, data + (int32_t)width * (int32_t)height * 3),
165-
(int32_t)width,
166-
(int32_t)height,
167-
3}},
168-
prompt.UTF8String,
169-
seq_len,
170-
[callback](const std::string& token) { callback(@(token.c_str())); });
171-
if (status != Error::Ok) {
172-
if (error) {
173-
*error = [NSError errorWithDomain:LLaMARunnerErrorDomain
174-
code:(NSInteger)status
175-
userInfo:nil];
176-
return NO;
177-
}
178-
}
179-
return YES;
180-
}
181-
182-
- (void)stop {
183-
_runner->stop();
184-
}
185-
186-
#pragma mark - ExecuTorchLogSink
187-
188-
- (void)logWithLevel:(ExecuTorchLogLevel)level
189-
timestamp:(NSTimeInterval)timestamp
190-
filename:(NSString*)filename
191-
line:(NSUInteger)line
192-
message:(NSString*)message {
193-
NSUInteger totalSeconds = (NSUInteger)timestamp;
194-
NSUInteger hours = (totalSeconds / 3600) % 24;
195-
NSUInteger minutes = (totalSeconds / 60) % 60;
196-
NSUInteger seconds = totalSeconds % 60;
197-
NSUInteger microseconds = (timestamp - totalSeconds) * 1000000;
198-
NSLog(
199-
@"%c %02lu:%02lu:%02lu.%06lu executorch:%s:%zu] %s",
200-
(char)level,
201-
hours,
202-
minutes,
203-
seconds,
204-
microseconds,
205-
filename.UTF8String,
206-
line,
207-
message.UTF8String);
208-
}
209-
210-
@end
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
* All rights reserved.
4+
*
5+
* This source code is licensed under the BSD-style license found in the
6+
* LICENSE file in the root directory of this source tree.
7+
*/
8+
9+
#import <UIKit/UIKit.h>
10+
11+
NS_ASSUME_NONNULL_BEGIN
12+
13+
FOUNDATION_EXPORT NSErrorDomain const LLaVARunnerErrorDomain;
14+
15+
@interface LLaVARunner : NSObject
16+
17+
- (instancetype)initWithModelPath:(NSString*)filePath
18+
tokenizerPath:(NSString*)tokenizerPath;
19+
- (BOOL)isLoaded;
20+
- (BOOL)loadWithError:(NSError**)error;
21+
- (BOOL)generate:(void*)imageBuffer
22+
width:(CGFloat)width
23+
height:(CGFloat)height
24+
prompt:(NSString*)prompt
25+
sequenceLength:(NSInteger)seq_len
26+
withTokenCallback:(nullable void (^)(NSString*))callback
27+
error:(NSError**)error;
28+
- (void)stop;
29+
30+
+ (instancetype)new NS_UNAVAILABLE;
31+
- (instancetype)init NS_UNAVAILABLE;
32+
33+
@end
34+
35+
NS_ASSUME_NONNULL_END

0 commit comments

Comments
 (0)