<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Vivek Kumar Singh</title>
    <description>The latest articles on DEV Community by Vivek Kumar Singh (@darkryoshin).</description>
    <link>https://dev.to/darkryoshin</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4245595%2F3988b308-a082-4011-a348-2963fd79d3b7.jpg</url>
      <title>DEV Community: Vivek Kumar Singh</title>
      <link>https://dev.to/darkryoshin</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/darkryoshin"/>
    <language>en</language>
    <item>
      <title>Running Llama 3.2 &amp; Qwen 2.5 100% Offline in React Native &amp; Expo 52: Solving Thermal Throttling, OOMs, and Background Streaming</title>
      <dc:creator>Vivek Kumar Singh</dc:creator>
      <pubDate>Sun, 15 Nov 2026 08:30:06 +0000</pubDate>
      <link>https://dev.to/darkryoshin/running-llama-32-qwen-25-100-offline-in-react-native-expo-52-solving-thermal-throttling-4dam</link>
      <guid>https://dev.to/darkryoshin/running-llama-32-qwen-25-100-offline-in-react-native-expo-52-solving-thermal-throttling-4dam</guid>
      <description>&lt;p&gt;Running Large Language Models (LLMs) locally on a smartphone used to feel like science fiction. But with quantized GGUF architectures and optimized native runtimes like &lt;code&gt;llama.rn&lt;/code&gt;, modern mobile chipsets can now execute capable models (like Llama 3.2 1B/3B and Qwen 2.5 1.5B) entirely on-device.&lt;/p&gt;

&lt;p&gt;No cloud dependencies, zero monthly OpenAI/Anthropic API bills, and 100% data privacy for users.&lt;/p&gt;

&lt;p&gt;However, moving from a proof-of-concept script to a real, production-ready React Native app reveals three major engineering hurdles:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Thermal runaway &amp;amp; OS OOM kills: Continuous token generation pushes the CPU/GPU hard, causing the Android OS Low-Memory Killer (OOM) to terminate the app.&lt;/li&gt;
&lt;li&gt;Background thread freezing: The moment a user minimizes the app or locks their screen, the JS thread pauses and streaming stops.&lt;/li&gt;
&lt;li&gt;Document and image parsing: Processing PDFs, DOCX, and images on-device without calling third-party cloud APIs.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Here is how I tackled each of these challenges in Expo 52.&lt;/p&gt;




&lt;ol&gt;
&lt;li&gt;Adaptive C++ Duty-Cycle Throttling&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;When running native inference via &lt;code&gt;llama.rn&lt;/code&gt;, the decode loop consumes 100% of available processor cores by default. On a desktop or server with active cooling, this is fine. On a smartphone, the chassis rapidly heats up, triggering hardware thermal throttling and aggressive OS process pruning.&lt;/p&gt;

&lt;p&gt;The Solution:&lt;br&gt;&lt;br&gt;
We patched the native C++ decode loop to introduce configurable, adaptive duty-cycle pauses between generation slices. By yielding execution for a few milliseconds between token chunks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SoC temperature drops by over 8°C.&lt;/li&gt;
&lt;li&gt;Sustained memory overhead remains predictable (850MB – 1.3GB RAM).&lt;/li&gt;
&lt;li&gt;The Android Low-Memory Killer never triggers.&lt;/li&gt;
&lt;/ul&gt;




&lt;ol&gt;
&lt;li&gt;Dedicated Android Foreground Service&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Mobile operating systems are ruthless with background tasks. If generation takes 15–20 seconds and the user locks their screen to put their phone in their pocket, the generation usually dies.&lt;/p&gt;

&lt;p&gt;The Solution:&lt;br&gt;&lt;br&gt;
We built a custom native Android Foreground Service with wake locks and persistent notification controls. While inference runs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A notification bar shows live streaming progress with a one-tap "Stop" action.&lt;/li&gt;
&lt;li&gt;The CPU wake lock guarantees generation finishes cleanly even if the phone screen is turned off.&lt;/li&gt;
&lt;/ul&gt;




&lt;ol&gt;
&lt;li&gt;Multimodal OCR &amp;amp; Local Document Extraction&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;A modern AI assistant needs to understand documents and photos. Rather than shipping user documents to a cloud endpoint:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Camera &amp;amp; Photo OCR: We integrated &lt;code&gt;expo-mlkit-ocr&lt;/code&gt; to extract text from images directly using Google ML Kit on-device.&lt;/li&gt;
&lt;li&gt;Native Document Reader: A custom Android native module extracts text from local PDFs (up to 64 pages) and Word &lt;code&gt;.docx&lt;/code&gt; files on the device filesystem.&lt;/li&gt;
&lt;/ul&gt;




&lt;ol&gt;
&lt;li&gt;Atomic SQLite Response Checkpointing&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If a user receives a phone call during token generation, the app might be paused. To prevent losing generated text, we stream tokens into a local SQLite database every 2 seconds. If anything interrupts generation, the conversation state is preserved and seamlessly resumable.&lt;/p&gt;




&lt;p&gt;Real Hardware Benchmarks&lt;/p&gt;

&lt;p&gt;Tested on a physical Motorola Edge 50 Neo (MediaTek Dimensity 7300, 8GB RAM, Android 14/15):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Llama 3.2 1B Instruct (Q4_K_M): ~18–25 tokens/sec&lt;/li&gt;
&lt;li&gt;Qwen 2.5 1.5B Instruct (Q4_K_M): ~10–14 tokens/sec&lt;/li&gt;
&lt;li&gt;Memory footprint: 800MB–1.4GB RAM ceiling&lt;/li&gt;
&lt;li&gt;Cold model load time: ~1.2s from flash storage&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Explore the Architecture &amp;amp; Starter Kit&lt;/p&gt;

&lt;p&gt;I've made the architecture breakdown, benchmark documentation, and screenshots publicly available on GitHub:&lt;/p&gt;

&lt;p&gt;👉 GitHub Repository: &lt;a href="https://github.com/Itsvks17/localai-mobile" rel="noopener noreferrer"&gt;https://github.com/Itsvks17/localai-mobile&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For developers and indie founders looking to build their own local AI mobile apps without spending weeks debugging native C++ throttles and Android foreground services, I also packaged a turnkey starter kit with all custom native modules and 119 automated regression tests on Gumroad:&lt;/p&gt;

&lt;p&gt;👉 Starter Kit on Gumroad: &lt;a href="https://darkryoshin.gumroad.com/l/localai-mobile" rel="noopener noreferrer"&gt;https://darkryoshin.gumroad.com/l/localai-mobile&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Feel free to star the repo or ask questions below about mobile GGUF quantization, Expo config plugins, or memory tuning!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fir5twcivsxe6eobdxebk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fir5twcivsxe6eobdxebk.png" alt=" " width="800" height="1780"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6vwhn2zahl1w7j7pndjy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F6vwhn2zahl1w7j7pndjy.png" alt=" " width="800" height="1780"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqp7vz5unz5xd52eotyax.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fqp7vz5unz5xd52eotyax.png" alt=" " width="800" height="1780"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpx6tj7tk1pk3cvgdnzsw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fpx6tj7tk1pk3cvgdnzsw.png" alt=" " width="800" height="1780"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>ai</category>
      <category>llm</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
