@dr33m/react-native-litert-lm 0.5.3 → 0.5.4

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.
@@ -58,6 +58,10 @@ class HybridLiteRTLM : HybridLiteRTLMSpec() {
58
58
  /** Cached result of OpenCL availability probe (null = not yet checked). */
59
59
  @Volatile
60
60
  private var openCLAvailable: Boolean? = null
61
+
62
+ /** Cached result of NPU/QNN availability probe (null = not yet checked). */
63
+ @Volatile
64
+ private var npuAvailable: Boolean? = null
61
65
 
62
66
  /**
63
67
  * Initialize the native library.
@@ -197,6 +201,41 @@ class HybridLiteRTLM : HybridLiteRTLMSpec() {
197
201
  }
198
202
  }
199
203
 
204
+ // NPU hardware check: probe for QNN HTP runtime libraries.
205
+ // LiteRT-LM's NPU delegate requires Qualcomm QNN HTP (Hexagon Tensor
206
+ // Processor) runtime. Without it, Engine() crashes with SIGSEGV
207
+ // that Kotlin's try/catch cannot intercept.
208
+ // Unlike GPU (which throws a catchable Java exception on failure),
209
+ // NPU failure is a native crash — so we MUST detect before attempting.
210
+ if (npuAvailable == null) {
211
+ val hasNpu = run {
212
+ // Check for QNN HTP libraries in system vendor paths.
213
+ // These are only present on devices with Qualcomm NPU support.
214
+ val qnnPaths = arrayOf(
215
+ "/vendor/lib64/libQnnHtp.so",
216
+ "/vendor/lib/libQnnHtp.so",
217
+ "/system/vendor/lib64/libQnnHtp.so",
218
+ "/system/lib64/libQnnHtp.so",
219
+ "/vendor/lib64/libQnnSystem.so",
220
+ "/vendor/lib/libQnnSystem.so"
221
+ )
222
+ var found = false
223
+ for (path in qnnPaths) {
224
+ if (java.io.File(path).exists()) {
225
+ found = true
226
+ break
227
+ }
228
+ }
229
+ found
230
+ }
231
+ npuAvailable = hasNpu
232
+ if (!hasNpu) {
233
+ Log.w(TAG, "QNN HTP libraries not found — NPU backend unavailable")
234
+ } else {
235
+ Log.i(TAG, "QNN HTP libraries found — NPU backend may be available")
236
+ }
237
+ }
238
+
200
239
  // Detect multimodal support. Check config.multimodal flag first, then fall back to filename sniffing.
201
240
  // Only Gemma 3n bundles vision/audio executors; Gemma 4 E2B is text-only.
202
241
  // Passing vision/audio backends to a text-only model causes
@@ -259,12 +298,13 @@ class HybridLiteRTLM : HybridLiteRTLMSpec() {
259
298
  }
260
299
  }
261
300
  Backend.NPU -> {
301
+ val hasNpu = npuAvailable ?: false
262
302
  val nativeLibDir = LiteRTLMInitProvider.applicationContext?.applicationInfo?.nativeLibraryDir
263
- Log.i(TAG, "NPU backend requested - nativeLibraryDir=$nativeLibDir")
264
- if (nativeLibDir != null) {
303
+ Log.i(TAG, "NPU backend requested - available=$hasNpu, nativeLibraryDir=$nativeLibDir")
304
+ if (hasNpu && nativeLibDir != null) {
265
305
  com.google.ai.edge.litertlm.Backend.NPU(nativeLibraryDir = nativeLibDir)
266
306
  } else {
267
- Log.w(TAG, "NPU requested but nativeLibraryDir unavailable — using CPU directly")
307
+ Log.w(TAG, "NPU requested but hardware unavailable — using CPU directly")
268
308
  backend = Backend.CPU
269
309
  com.google.ai.edge.litertlm.Backend.CPU()
270
310
  }
@@ -662,10 +702,10 @@ class HybridLiteRTLM : HybridLiteRTLMSpec() {
662
702
  tool(apiTool)
663
703
  }
664
704
 
665
- // Create conversation with explicit SamplerConfig (required by Gallery pattern).
666
- // GPU backend may fail silently without proper sampler params.
705
+ // Create conversation config. NPU backend does not support SamplerConfig
706
+ // (matching Gallery app pattern setting sampler params on NPU causes crashes).
667
707
  val convConfig = ConversationConfig(
668
- samplerConfig = SamplerConfig(
708
+ samplerConfig = if (backend == Backend.NPU) null else SamplerConfig(
669
709
  topK = topK,
670
710
  topP = topP.toDouble(),
671
711
  temperature = temperature.toDouble(),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dr33m/react-native-litert-lm",
3
- "version": "0.5.3",
3
+ "version": "0.5.4",
4
4
  "litertLm": {
5
5
  "version": "0.12.0",
6
6
  "androidMavenVersion": "0.12.0",