@novastera-oss/llamarn 0.1.3-beta.3 → 0.1.3-beta.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/android/CMakeLists.txt +54 -11
- package/cpp/PureCppImpl.cpp +1 -33
- package/package.json +1 -1
package/android/CMakeLists.txt
CHANGED
|
@@ -74,22 +74,59 @@ add_library(
|
|
|
74
74
|
target_compile_options(common PRIVATE -Wno-unused-function)
|
|
75
75
|
target_compile_options(RNLlamaCpp PRIVATE -Wno-unused-function)
|
|
76
76
|
|
|
77
|
+
# Check if Vulkan backend library is available
|
|
78
|
+
set(VULKAN_BACKEND_AVAILABLE FALSE)
|
|
79
|
+
if(EXISTS ${JNI_LIBS_DIR}/${ANDROID_ABI}/libggml-vulkan.so)
|
|
80
|
+
set(VULKAN_BACKEND_AVAILABLE TRUE)
|
|
81
|
+
message(STATUS "Vulkan backend library found for ${ANDROID_ABI}")
|
|
82
|
+
else()
|
|
83
|
+
message(STATUS "Vulkan backend library not found for ${ANDROID_ABI}")
|
|
84
|
+
endif()
|
|
85
|
+
|
|
86
|
+
# Check if OpenCL backend library is available
|
|
87
|
+
set(OPENCL_BACKEND_AVAILABLE FALSE)
|
|
88
|
+
if(EXISTS ${JNI_LIBS_DIR}/${ANDROID_ABI}/libggml-opencl.so AND EXISTS ${JNI_LIBS_DIR}/${ANDROID_ABI}/libOpenCL.so)
|
|
89
|
+
set(OPENCL_BACKEND_AVAILABLE TRUE)
|
|
90
|
+
message(STATUS "OpenCL backend libraries found for ${ANDROID_ABI}")
|
|
91
|
+
else()
|
|
92
|
+
message(STATUS "OpenCL backend libraries not found for ${ANDROID_ABI}")
|
|
93
|
+
endif()
|
|
94
|
+
|
|
77
95
|
# Hybrid backend approach: CPU static (built into main libraries), GPU dynamic
|
|
78
96
|
# CPU backend will be statically linked into main libraries (libggml.so, libllama.so)
|
|
79
|
-
# GPU backends (OpenCL, Vulkan) will be dynamically loaded at runtime
|
|
97
|
+
# GPU backends (OpenCL, Vulkan) will be dynamically loaded at runtime only if available
|
|
80
98
|
target_compile_definitions(common PRIVATE
|
|
81
99
|
-DGGML_BACKEND_DL=1 # Enable dynamic loading for GPU backends
|
|
82
100
|
-DGGML_CPU=1 # CPU backend statically built into main libraries
|
|
83
|
-
-DGGML_VULKAN=1 # Enable Vulkan backend support for dynamic loading
|
|
84
|
-
-DGGML_OPENCL=1 # Enable OpenCL backend support for dynamic loading
|
|
85
101
|
)
|
|
86
102
|
target_compile_definitions(RNLlamaCpp PRIVATE
|
|
87
103
|
-DGGML_BACKEND_DL=1 # Enable dynamic loading for GPU backends
|
|
88
104
|
-DGGML_CPU=1 # CPU backend statically built into main libraries
|
|
89
|
-
-DGGML_VULKAN=1 # Enable Vulkan backend support for dynamic loading
|
|
90
|
-
-DGGML_OPENCL=1 # Enable OpenCL backend support for dynamic loading
|
|
91
105
|
)
|
|
92
106
|
|
|
107
|
+
# DISABLE Vulkan on Android - causes crashes during auto-initialization on emulators
|
|
108
|
+
# Even with n_gpu_layers=0, llama.cpp tries to initialize all available backends
|
|
109
|
+
message(STATUS "Vulkan backend support DISABLED on Android to prevent emulator crashes")
|
|
110
|
+
|
|
111
|
+
# TODO: Enable Vulkan backend if available (currently disabled due to emulator crashes)
|
|
112
|
+
# Uncomment the lines below to test Vulkan support on real devices
|
|
113
|
+
# if(VULKAN_BACKEND_AVAILABLE)
|
|
114
|
+
# target_compile_definitions(common PRIVATE -DGGML_VULKAN=1)
|
|
115
|
+
# target_compile_definitions(RNLlamaCpp PRIVATE -DGGML_VULKAN=1)
|
|
116
|
+
# message(STATUS "Vulkan backend support enabled for dynamic loading")
|
|
117
|
+
# else()
|
|
118
|
+
# message(STATUS "Vulkan backend support disabled - library not available")
|
|
119
|
+
# endif()
|
|
120
|
+
|
|
121
|
+
# Enable OpenCL backend if available
|
|
122
|
+
if(OPENCL_BACKEND_AVAILABLE)
|
|
123
|
+
target_compile_definitions(common PRIVATE -DGGML_OPENCL=1)
|
|
124
|
+
target_compile_definitions(RNLlamaCpp PRIVATE -DGGML_OPENCL=1)
|
|
125
|
+
message(STATUS "OpenCL backend support enabled for dynamic loading")
|
|
126
|
+
else()
|
|
127
|
+
message(STATUS "OpenCL backend support disabled - library not available")
|
|
128
|
+
endif()
|
|
129
|
+
|
|
93
130
|
# Include directories
|
|
94
131
|
target_include_directories(common PRIVATE
|
|
95
132
|
${CPP_DIR}
|
|
@@ -161,12 +198,18 @@ add_custom_command(TARGET RNLlamaCpp POST_BUILD
|
|
|
161
198
|
|
|
162
199
|
# Also copy any optional GPU libraries if they exist
|
|
163
200
|
if(EXISTS ${JNI_LIBS_DIR}/${ANDROID_ABI}/libggml-vulkan.so)
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
201
|
+
# Don't copy Vulkan backend on Android - it crashes on emulators during auto-initialization
|
|
202
|
+
# Even with n_gpu_layers=0, llama.cpp tries to initialize all available backends
|
|
203
|
+
# and the Android emulator Vulkan driver is broken
|
|
204
|
+
message(STATUS "Skipping Vulkan backend copy to prevent emulator crashes")
|
|
205
|
+
|
|
206
|
+
# TODO: Uncomment the lines below to enable Vulkan library copying for testing on real devices
|
|
207
|
+
# add_custom_command(TARGET RNLlamaCpp POST_BUILD
|
|
208
|
+
# COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
|
209
|
+
# ${JNI_LIBS_DIR}/${ANDROID_ABI}/libggml-vulkan.so
|
|
210
|
+
# $<TARGET_FILE_DIR:RNLlamaCpp>/libggml-vulkan.so
|
|
211
|
+
# COMMENT "Copying Vulkan backend library to build output directory"
|
|
212
|
+
# )
|
|
170
213
|
endif()
|
|
171
214
|
|
|
172
215
|
if(EXISTS ${JNI_LIBS_DIR}/${ANDROID_ABI}/libggml-opencl.so)
|
package/cpp/PureCppImpl.cpp
CHANGED
|
@@ -245,40 +245,8 @@ jsi::Value PureCppImpl::initLlama(jsi::Runtime &runtime, jsi::Object options) {
|
|
|
245
245
|
throw std::runtime_error("Failed to initialize model and context");
|
|
246
246
|
}
|
|
247
247
|
} catch (const std::exception& e) {
|
|
248
|
-
std::string error_msg = e.what();
|
|
249
|
-
|
|
250
|
-
// Check for specific Vulkan errors that indicate Adreno GPU shader incompatibility
|
|
251
|
-
bool isVulkanShaderError = (
|
|
252
|
-
error_msg.find("createComputePipeline") != std::string::npos ||
|
|
253
|
-
error_msg.find("ErrorUnknown") != std::string::npos ||
|
|
254
|
-
error_msg.find("matmul_q4_k") != std::string::npos ||
|
|
255
|
-
error_msg.find("matmul_q5_k") != std::string::npos ||
|
|
256
|
-
error_msg.find("dequant_q4_K") != std::string::npos ||
|
|
257
|
-
error_msg.find("dequant_q5_K") != std::string::npos ||
|
|
258
|
-
error_msg.find("vulkan") != std::string::npos
|
|
259
|
-
);
|
|
260
|
-
|
|
261
248
|
// If we were trying to use GPU and got a Vulkan/shader error, retry with CPU-only
|
|
262
|
-
if (params.n_gpu_layers > 0
|
|
263
|
-
fprintf(stderr, "Vulkan shader compilation failed (likely Adreno GPU incompatibility): %s\n", e.what());
|
|
264
|
-
fprintf(stderr, "This is a known issue with Q4_K/Q5_K shaders on Qualcomm Adreno GPUs\n");
|
|
265
|
-
fprintf(stderr, "Retrying with CPU-only mode...\n");
|
|
266
|
-
|
|
267
|
-
// Retry with CPU-only
|
|
268
|
-
params.n_gpu_layers = 0;
|
|
269
|
-
|
|
270
|
-
try {
|
|
271
|
-
result = common_init_from_params(params);
|
|
272
|
-
|
|
273
|
-
if (!result.model || !result.context) {
|
|
274
|
-
throw std::runtime_error("Failed to initialize model and context even with CPU-only mode");
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
fprintf(stderr, "Successfully recovered with CPU-only mode after Vulkan shader failure\n");
|
|
278
|
-
} catch (const std::exception& cpu_e) {
|
|
279
|
-
throw std::runtime_error(std::string("Model initialization failed: ") + cpu_e.what());
|
|
280
|
-
}
|
|
281
|
-
} else if (params.n_gpu_layers > 0) {
|
|
249
|
+
if (params.n_gpu_layers > 0) {
|
|
282
250
|
// Other GPU error, still try CPU fallback
|
|
283
251
|
fprintf(stderr, "GPU initialization failed (%s), retrying with CPU-only\n", e.what());
|
|
284
252
|
|