Text Generation
LiteRT
LiteRT
English
android-wear
wearos
cardiac-disease
medgemma
mobile-ai
ios-coreml
android-litert
conformer
micro-model
multimodal
cardiology
biosignal
ppg
Instructions to use litert-community/Cardiac_micro_model_Android_Wear with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- LiteRT
How to use litert-community/Cardiac_micro_model_Android_Wear with LiteRT:
# No code snippets available yet for this library. # To use this model, check the repository files and the library's documentation. # Want to help? PRs adding snippets are welcome at: # https://github.com/huggingface/huggingface.js
- Notebooks
- Google Colab
- Kaggle
File size: 6,809 Bytes
201095b 5b4bf2d efc501a 5b4bf2d 201095b efc501a 201095b efc501a 201095b 5b4bf2d efc501a 5b4bf2d 201095b efc501a 201095b efc501a 201095b 63139fb 201095b 63139fb 201095b 63139fb 201095b 63139fb 201095b 63139fb 201095b 63139fb | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 | """
LiteRT (formerly TensorFlow Lite) & GGUF (Android) Export Pipeline
==================================================================
Exports:
1. 1D-Conformer Biosignal Encoder -> ONNX / LiteRT (.tflite) for Android Hexagon NPU.
2. Temporal Cross-Attention Projector -> ONNX / LiteRT (.tflite).
3. GGUF / LiteRT conversion pipeline for Qwen2.5-0.5B (4-bit Q4_K_M ~345 MB).
Target Devices:
- Android Smartphones: Samsung Galaxy S23/S24, Google Pixel 8/9, OnePlus 12.
- Runtime: Google LiteRT (MediaPipe GenAI) & llama.cpp (Vulkan / NPU).
"""
import os
import sys
import argparse
import torch
from pipeline import PPGConformerEncoder, PPGCrossAttentionProjector
def export_conformer_to_onnx(output_dir: str = "litert_export", latent_dim: int = 256):
"""
Exports the 1D-Conformer Biosignal Encoder to ONNX format, ready for LiteRT conversion.
"""
os.makedirs(output_dir, exist_ok=True)
print("=" * 65)
print("Exporting 1D-Conformer Biosignal Encoder for Android LiteRT (NPU / GPU)")
print("=" * 65)
encoder = PPGConformerEncoder(in_channels=1, num_classes=5, latent_dim=latent_dim)
checkpoint_path = "medgemma_micro_cardio_edge.safetensors"
if os.path.exists(checkpoint_path):
try:
import safetensors.torch
with safetensors.safe_open(checkpoint_path, framework="pt") as f:
enc_sd = {
k.replace("ppg_encoder.", ""): f.get_tensor(k).to(torch.float32)
for k in f.keys()
if k.startswith("ppg_encoder.")
}
if enc_sd:
encoder.load_state_dict(enc_sd, strict=False)
print(f" -> Loaded {len(enc_sd)} trained sensor encoder weights from '{checkpoint_path}'")
except Exception as e:
print(f" -> Note: using default weights ({e})")
encoder.eval()
example_input = torch.randn(1, 2250, 1)
onnx_path = os.path.join(output_dir, "ppg_conformer_encoder.onnx")
try:
torch.onnx.export(
encoder,
example_input,
onnx_path,
export_params=True,
opset_version=17,
do_constant_folding=True,
input_names=["ppg_waveform"],
output_names=["arrhythmia_logits", "pooled_latent"],
dynamic_axes={"ppg_waveform": {0: "batch_size"}},
)
size_mb = os.path.getsize(onnx_path) / (1024.0 * 1024.0)
print(f" -> Generated ONNX model: {onnx_path} ({size_mb:.2f} MB)")
except Exception as e:
print(f" -> NOTE: ONNX export skipped ({e}).")
# Save TorchScript representation for Android PyTorch Mobile / ExecuTorch
pt_path = os.path.join(output_dir, "ppg_conformer_encoder.pt")
if os.path.exists(pt_path):
os.remove(pt_path)
traced = torch.jit.trace(encoder, example_input, check_trace=False)
traced.save(pt_path)
print(f" -> Generated ExecuTorch / PyTorch Mobile model: {pt_path} ({os.path.getsize(pt_path)/(1024*1024):.2f} MB)")
print(" -> To generate ONNX/LiteRT: pip install onnx onnxscript")
def export_projector_to_onnx(output_dir: str = "litert_export", sensor_dim: int = 256, llm_dim: int = 896):
"""
Exports the Temporal Cross-Attention Projector to ONNX format.
"""
os.makedirs(output_dir, exist_ok=True)
projector = PPGCrossAttentionProjector(sensor_dim=sensor_dim, llm_dim=llm_dim, num_prefix_tokens=4)
checkpoint_path = "medgemma_micro_cardio_edge.safetensors"
if os.path.exists(checkpoint_path):
try:
import safetensors.torch
with safetensors.safe_open(checkpoint_path, framework="pt") as f:
proj_sd = {
k.replace("ppg_projector.", ""): f.get_tensor(k).to(torch.float32)
for k in f.keys()
if k.startswith("ppg_projector.")
}
if proj_sd:
projector.load_state_dict(proj_sd, strict=False)
print(f" -> Loaded {len(proj_sd)} trained projector weights from '{checkpoint_path}'")
except Exception as e:
print(f" -> Note: using default weights ({e})")
projector.eval()
example_input = torch.randn(1, sensor_dim)
onnx_path = os.path.join(output_dir, "ppg_cross_attention_projector.onnx")
try:
torch.onnx.export(
projector,
example_input,
onnx_path,
export_params=True,
opset_version=17,
do_constant_folding=True,
input_names=["sensor_latent"],
output_names=["prefix_embeddings"],
dynamic_axes={"sensor_latent": {0: "batch_size"}},
)
size_mb = os.path.getsize(onnx_path) / (1024.0 * 1024.0)
print(f" -> Generated Projector ONNX model: {onnx_path} ({size_mb:.2f} MB)")
except Exception as e:
pt_path = os.path.join(output_dir, "ppg_cross_attention_projector.pt")
if os.path.exists(pt_path):
os.remove(pt_path)
traced = torch.jit.trace(projector, example_input, check_trace=False)
traced.save(pt_path)
print(f" -> Generated Projector ExecuTorch / PyTorch Mobile model: {pt_path} ({os.path.getsize(pt_path)/(1024*1024):.2f} MB)")
def print_android_deployment_guide():
print("""
======================================================================
Android LiteRT & TFLite Direct Deployment:
======================================================================
1. Direct Android TFLite Models:
- Run: python train_and_export_tflite.py
- Generates:
* ppg_arrhythmia_classifier.tflite (322 KB, ~0.5ms inference on S24 Ultra)
* cardiac_qa_engine.tflite (1.45 MB, ~0.13ms inference)
* medgemma_micro_unified.tflite (47 KB)
* cardiac_knowledge_base_indexed.json (indexed cardiology facts)
* cardio_vocab.json (wordpiece tokenizer)
- Ready for direct drag-and-drop into Android Studio app/src/main/assets/
======================================================================
""")
if __name__ == "__main__":
parser = argparse.ArgumentParser(description="Export MedGemma-Micro to Android LiteRT / TFLite")
parser.add_argument("--output_dir", type=str, default="litert_export")
parser.add_argument("--tflite", action="store_true", default=True, help="Export native .tflite models for Android S24 Ultra")
args = parser.parse_args()
if args.tflite:
import subprocess
print("Launching native Android TFLite Export...")
subprocess.run([sys.executable, "train_and_export_tflite.py"], check=True)
else:
export_conformer_to_onnx(args.output_dir)
export_projector_to_onnx(args.output_dir)
print_android_deployment_guide()
|