一個基於 Flutter + Dart FFI + llama.cpp + Llama 3.2 1B 開發的完全離線 AI 健康助理。
使用者輸入每日生理與生活數據後,App 會透過手機本地端的 LLM 即時生成個人化健康報告。所有 AI 推理皆在裝置端完成,不需要連接網路,也不會將健康資料上傳至雲端。
核心特色:On-Device AI · Fully Offline · Privacy First
使用者可以輸入每日健康相關數據:
- 體重
- 步數
- 睡眠時數
- 運動分鐘數
- 心情評分
資料儲存在裝置本地端,不需要透過後端 API 傳送至雲端。
根據使用者當日輸入的健康數據,建立 Prompt 並交由手機本地端 LLM 進行推理,生成個人化健康報告。
報告包含:
- 現況評估
- 需要留意的地方
- 具體生活建議
- 非醫療診斷提醒
所有內容皆由裝置端模型即時生成。
模型直接隨 App 打包:
assets/
└── models/
└── Llama-3.2-1B-Instruct-Q4_K_M.gguf
首次啟動 App 時:
Flutter Assets
│
▼
複製 GGUF Model
│
▼
App Local Storage
│
▼
llama.cpp 載入模型
模型載入完成後,AI 推理完全在手機本地端執行:
- ❌ 不需要 Internet
- ❌ 不需要 Cloud API
- ❌ 不需要 Server
- ❌ 不上傳使用者健康資料
- ✅ On-Device Inference
本專案使用:
Llama-3.2-1B-Instruct-Q4_K_M.gguf
| 項目 | 說明 |
|---|---|
| Model | Llama 3.2 1B Instruct |
| Parameters | 1 Billion |
| Quantization | Q4_K_M |
| Format | GGUF |
| Runtime | llama.cpp |
| Execution | CPU / ARM NEON |
| Deployment | On-Device |
| Download | Hugging Face |
整個系統分成四個主要 Layer:
┌────────────────────────────────────────────────────┐
│ Flutter UI │
│ │
│ lib/health_report_page.dart │
│ │
│ • 輸入健康數據 │
│ • 產生健康報告 │
│ • Streaming UI │
└──────────────────────┬─────────────────────────────┘
│
│ Dart
▼
┌────────────────────────────────────────────────────┐
│ LlamaEngineService │
│ │
│ lib/llama_engine_service.dart │
│ │
│ • Engine lifecycle │
│ • Isolate management │
│ • Model initialization │
│ • Streaming generation │
│ • Resource disposal │
└──────────────────────┬─────────────────────────────┘
│
│ dart:ffi
▼
┌────────────────────────────────────────────────────┐
│ Native Bridge │
│ │
│ native_bridge.dart │
│ native_lib.cpp │
│ │
│ • Dart ↔ C/C++ bridge │
│ • FFI function binding │
│ • Token callback │
└──────────────────────┬─────────────────────────────┘
│
│ C/C++
▼
┌────────────────────────────────────────────────────┐
│ llama.cpp / ggml │
│ │
│ src/llama/ │
│ │
│ • Model loading │
│ • Tokenization │
│ • Prompt processing │
│ • Transformer inference │
│ • Token sampling │
│ • CPU / ARM NEON backend │
└────────────────────────────────────────────────────┘
以「產生健康報告」為例:
使用者輸入:
體重:70 kg
步數:8,500
睡眠:7.2 小時
運動:35 分鐘
心情:8 / 10
資料儲存在本機:
lib/health_data.dart
│
▼
Local JSON
App 將當日健康資料轉換成 Prompt:
請根據以下使用者今日健康資料,
提供一份簡短的健康狀況分析。
體重:70 kg
步數:8500
睡眠:7.2 小時
運動:35 分鐘
心情:8 / 10
請包含:
1. 現況評估
2. 需要留意的地方
3. 具體生活建議
最後提醒使用者:
以上內容僅供健康資訊參考,非醫療診斷。
Flutter UI
│
▼
LlamaEngineService.generate()
│
▼
Background Isolate
將模型推理工作放到 Background Isolate,避免大量 CPU 工作阻塞 Flutter UI Thread。
Dart 透過 dart:ffi 呼叫 C API:
Dart
│
│ FFI
▼
C/C++
主要 Native API:
c_init_llama_backend()
c_stream_inference()
c_free_llama_backend()Native 層將 Prompt 傳入 llama.cpp:
Prompt
│
▼
Tokenization
│
▼
Model Decode
│
▼
Token Sampling
│
▼
Next Token
│
└──────────────┐
│
▼
Next Token
│
...
每產生一個 Token,就透過 Native callback 回傳:
llama.cpp
│
▼
Native Callback
│
▼
Dart FFI
│
▼
SendPort
│
▼
Flutter UI
因此使用者可以看到報告即時生成:
目前的睡眠時間約為 7.2 小時,
整體來看...
而不是等待整份報告完成後一次顯示。
EdgeAssistant/
│
├── lib/
│ ├── health_report_page.dart
│ ├── health_data.dart
│ ├── llama_engine_service.dart
│ └── native_bridge.dart
│
├── android/
│ └── app/
│ └── src/
│ └── main/
│ └── cpp/
│ ├── native_lib.cpp
│ └── CMakeLists.txt
│
├── models/
│ └── Llama-3.2-1B-Instruct-Q4_K_M.gguf
│
├── src/
│ └── llama/
│ └── llama.cpp
│
└── README.md
完整使用流程:
┌─────────────────────┐
│ 開啟 EdgeAssistant │
└──────────┬──────────┘
│
▼
┌─────────────────────┐
│ 載入 Local GGUF │
│ Model │
└──────────┬──────────┘
│
▼
┌─────────────────────┐
│ 輸入今日健康資料 │
│ │
│ Weight │
│ Steps │
│ Sleep │
│ Exercise │
│ Mood │
└──────────┬──────────┘
│
▼
┌─────────────────────┐
│ 建立 Prompt │
└──────────┬──────────┘
│
▼
┌─────────────────────┐
│ Background Isolate │
└──────────┬──────────┘
│
▼
┌─────────────────────┐
│ Dart FFI │
└──────────┬──────────┘
│
▼
┌─────────────────────┐
│ Native C/C++ │
└──────────┬──────────┘
│
▼
┌─────────────────────┐
│ llama.cpp │
│ On-Device Inference │
└──────────┬──────────┘
│
│ Token Streaming
▼
┌─────────────────────┐
│ Flutter UI │
│ 即時顯示健康報告 │
└─────────────────────┘