środa, 24 września 2025

 Rozwinięcie kodu dla Androida: Integracja z TensorFlow Lite

Dla trybu online możesz użyć API (np. Grok 3) do wyszukiwania/analizy, ale dla offline/hybrydowego – TensorFlow Lite (TFLite) do uruchamiania zoptymalizowanych modeli LLM (np. Llama 3 lub Phi-3) na urządzeniu. TFLite jest lekkie, działa na CPU/GPU Androida i wspiera kwantyzację (zmniejszanie modelu do 4-bit, by zmieścił się w 4-8 GB RAM).Krok 1: Przygotowanie modelu
  • Pobierz model open-source (np. Llama 3 7B z Hugging Face).
  • Skonwertuj do formatu TFLite:
    bash
    # Użyj Pythona z TensorFlow (na komputerze)
    pip install tensorflow transformers
    python
    import tensorflow as tf
    from transformers import AutoModelForCausalLM, AutoTokenizer
    import torch
    
    model_name = "meta-llama/Llama-3-7b"
    model = AutoModelForCausalLM.from_pretrained(model_name, torch_dtype=torch.float16)
    tokenizer = AutoTokenizer.from_pretrained(model_name)
    
    # Konwersja do TFLite (uproszczona; użyj full guide z TensorFlow docs)
    converter = tf.lite.TFLiteConverter.from_saved_model("./optimized_model")
    converter.optimizations = [tf.lite.Optimize.DEFAULT]  # Kwantyzacja
    tflite_model = converter.convert()
    
    with open("model.tflite", "wb") as f:
        f.write(tflite_model)
    tokenizer.save_pretrained("./tokenizer")
  • Przenieś model.tflite i tokenizer do assets w Android Studio.
Krok 2: Integracja w aplikacji Android (Kotlin)Użyj Android Studio: Nowy projekt z Jetpack Compose (dla UI). Dodaj zależności w build.gradle (Module: app):
kotlin
dependencies {
    implementation("org.tensorflow:tensorflow-lite:2.15.0")
    implementation("org.tensorflow:tensorflow-lite-support:0.4.4")
    implementation("androidx.compose.ui:ui:1.6.0")  // Dla UI
    // ... inne
}
Przykład kodu: Prosta app z polem tekstowym, przyciskiem do zapytania i odpowiedzią od modelu. Hybrydowy tryb: Offline via TFLite, online via HTTP do API (np. Grok).
kotlin
// MainActivity.kt
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.*
import androidx.compose.material3.*
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import org.tensorflow.lite.Interpreter
import java.nio.MappedByteBuffer
import java.io.FileInputStream
import java.io.IOException
import java.nio.channels.FileChannel
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import okhttp3.*  // Dodaj OkHttp dla online
import java.io.InputStream

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            MaterialTheme {
                Surface(modifier = Modifier.fillMaxSize()) {
                    AgentScreen()
                }
            }
        }
    }
}

@Composable
fun AgentScreen() {
    var inputText by remember { mutableStateOf("") }
    var outputText by remember { mutableStateOf("") }
    var isOnline by remember { mutableStateOf(true) }  // Przełącznik trybu

    Column(modifier = Modifier.padding(16.dp)) {
        TextField(
            value = inputText,
            onValueChange = { inputText = it },
            label = { Text("Twoje zapytanie") },
            modifier = Modifier.fillMaxWidth()
        )
        Button(onClick = {
            // Wywołaj funkcję odpowiedzi
            outputText = if (isOnline) {
                // Online: API call (np. Grok)
                fetchOnlineResponse(inputText)
            } else {
                // Offline: TFLite
                runTFLiteInference(inputText)
            }
        }) {
            Text("Wyślij")
        }
        Text("Odpowiedź: $outputText")
        Switch(checked = isOnline, onCheckedChange = { isOnline = it })
        Text("Tryb online: $isOnline")
    }
}

// Funkcja offline: TFLite inference
fun runTFLiteInference(input: String): String {
    // Wczytaj model z assets
    val modelBuffer = loadModelFile("model.tflite")  // Implementuj loadModelFile poniżej
    val tflite = Interpreter(modelBuffer)

    // Tokenizacja (uproszczona; użyj full tokenizer)
    val tokenizerInput = tokenizeInput(input)  // Zaimplementuj z HuggingFace tokenizer (lub prosty)

    // Uruchom inferencję
    val output = Array(1) { FloatArray(1000) }  // Dostosuj wymiary
    tflite.run(tokenizerInput, output)

    tflite.close()
    return decodeOutput(output)  // Dekoduj do tekstu
}

// Ładowanie modelu z assets
@Throws(IOException::class)
private fun loadModelFile(modelPath: String): MappedByteBuffer {
    val fileDescriptor = assets.openFd(modelPath)
    val inputStream = FileInputStream(fileDescriptor.fileDescriptor)
    val fileChannel = inputStream.channel
    val startOffset = fileDescriptor.startOffset
    val declaredLength = fileDescriptor.declaredLength
    return fileChannel.map(FileChannel.MapMode.READ_ONLY, startOffset, declaredLength)
}

// Online: Przykładowy call do API (np. Grok)
suspend fun fetchOnlineResponse(query: String): String = withContext(Dispatchers.IO) {
    val client = OkHttpClient()
    val apiKey = "TWÓJ_KLUCZ"  // Z https://x.ai/api
    val json = """{"prompt": "$query"}"""
    val body = RequestBody.create("application/json".toMediaTypeOrNull(), json)
    val request = Request.Builder()
        .url("https://api.x.ai/grok3")  // Przykładowy endpoint
        .addHeader("Authorization", "Bearer $apiKey")
        .post(body)
        .build()

    val response = client.newCall(request).execute()
    return@withContext response.body?.string() ?: "Błąd"
}

// Helpery: tokenizeInput i decodeOutput – zaimplementuj z biblioteką jak SentencePiece lub prostym dict
fun tokenizeInput(text: String): FloatArray { /* ... */ return floatArrayOf() }
fun decodeOutput(output: Array<FloatArray>): String { /* ... */ return "Przykładowa odpowiedź" }
Krok 3: Dodatkowe funkcje
  • Wyszukiwanie/analiza online: W fetchOnlineResponse dodaj logikę do scraping'u (np. via Jsoup) lub API jak Google Search.
  • Lokalna baza: Użyj Room (SQLite) do przechowywania historii zapytań.
  • Testowanie: Uruchom na emulatorze z GPU. Dla voice: Dodaj SpeechRecognizer.
  • Optymalizacja: Użyj NNAPI dla przyspieszenia na nowszych Androidach.
To podstawowa struktura – app działa offline z TFLite, online z API. Jeśli chcesz pełny projekt GitHub lub rozszerzenie (np. RAG z bazą wektorową), daj znać. Co myślisz o tych znaleziskach z X?

Brak komentarzy:

Prześlij komentarz