עוזר AI לא מקוון ב-iOS וב-Android עם Llama.cpp

עוזרי AI מבוססי ענן דורשים חיבור קבוע ומעבירים נתונים רגישים לשרתים, דבר שאינו מקובל בתחומי הרפואה והפיננסים. אנו משלבים את Llama.cpp באפליקציות iOS ו-Android, ובונים עוזרים לא מקוונים הפועלים כולו על המכשיר. הצוות שלנו מספק פרויקטים סוהר—מבחירת המודל ועד אופטימיזציה של ביצועים—ומבטיח פעולה אמינה ותמיכה מתמשכת.

פיתוח ותמיכה בכל סוגי היישומים הניידים:

יישומים ניידים למידע ובידור
אפליקציות חדשות, משחקים, מדריכים, קטלוגים מקוונים, אפליקציות מזג אוויר, אפליקציות כושר ובריאות, אפליקציות נסיעות, אפליקציות חינוכיות, רשתות חברתיות ומסנג'רים, חידונים, בלוגים ופודקאסטים, פורומים, אגרגטורים
יישומים ניידים למסחר אלקטרוני
חנויות מקוונות, אפליקציות B2B, מרקטפלייסים, בורסות מקוונות, שירותי קאשבק, בורסות, פלטפורמות דרופשיפינג, תוכניות נאמנות, משלוחי מזון ומוצרים, מערכות תשלום.
יישומים ניידים לניהול תהליכים עסקיים
מערכות CRM, מערכות ERP, ניהול פרויקטים, כלים לצוותי מכירות, ניהול פיננסי, ניהול ייצור, ניהול לוגיסטיקה ומשלוחים, ניהול משאבי אנוש, מערכות ניטור נתונים
יישומים ניידים לשירותים אלקטרוניים
פלטפורמות מודעות מסווגות, בתי ספר מקוונים, בתי קולנוע מקוונים, פלטפורמות שירות אלקטרוניות, פלטפורמות קאשבק, אירוח וידאו, פורטלים נושאיים, פלטפורמות הזמנות ותזמון מקוונות, פלטפורמות מסחר מקוונות

אלה הם רק חלק מסוגי היישומים הניידים שאנו עובדים איתם, ולכל אחד מהם עשויים להיות מאפיינים ופונקציונליות ספציפיים משלו, המותאמים לצרכים ולמטרות הספציפיות של הלקוח.

השירותים שאנו מציעים
מציג 1 מתוך 1כל 1734 השירותים
עוזר AI לא מקוון ב-iOS וב-Android עם Llama.cpp
מורכב
~2-4 שבועות

הכישורים שלנו:

שאלות נפוצות

העבודות האחרונות

  • פיתוח אפליקציית מובייל עבור FEEDME
    פיתוח אפליקציית מובייל עבור FEEDME
    971
  • פיתוח אפליקציית מובייל עבור XOOMER
    פיתוח אפליקציית מובייל עבור XOOMER
    869
  • פיתוח אפליקציית מובייל עבור RHL
    פיתוח אפליקציית מובייל עבור RHL
    1289
  • פיתוח אפליקציית מובייל עבור ZIPPY
    פיתוח אפליקציית מובייל עבור ZIPPY
    1143
  • פיתוח אפליקציית מובייל עבור Affhome
    פיתוח אפליקציית מובייל עבור Affhome
    1076
  • פיתוח אפליקציית מובייל עבור חברת FLAVORS
    פיתוח אפליקציית מובייל עבור חברת FLAVORS
    677

תארו לעצמכם: עוזר AI באפליקציה ניידת עובד במצב לא מקוון, כל הנתונים נשארים במכשיר. אין העברות לשרת, אין השהיית רשת. מודלי LLM בענן דורשים קישוריות קבועה, מעבירים נתונים רגישים וגורמים לעיכובים. עבור רפואה או פיננסים, זה בלתי מתקבל על הדעת. פתרון במכשיר פותר את הבעיות הללו אך דורש אינטגרציה קפדנית ספציפית לפלטפורמה. אנו משלבים את Llama.cpp — ספריית הסקת LLM על CPU/GPU — באפליקציות iOS ו-Android. בואו נצלול לפרטים הטכניים: מבחירת מודל ועד ניהול תרמי.

איך לבחור מודל לעוזר לא מקוון?

Llama.cpp עובד עם מודלים בפורמט GGUF. אפשרויות פופולריות לנייד:

מודל קוונטיזציה גודל RAM מהירות (iPhone 14)
Llama-3.2-1B Q4_K_M 0.8 GB ~1.2 GB 25–35 t/s
Llama-3.2-3B Q4_K_M 2.0 GB ~2.5 GB 10–15 t/s
Phi-3-mini-4k Q4_K_M 2.2 GB ~2.8 GB 8–12 t/s
Gemma-2-2B Q4_K_M 1.6 GB ~2.0 GB 12–18 t/s
Qwen2.5-1.5B Q4_K_M 1.0 GB ~1.4 GB 20–28 t/s

ב-iPhone SE דור 2 (3 GB RAM), Llama-3.2-3B Q4 פועל בגבול היכולת — OOM אפשרי עם הקשרים ארוכים. בחירה בטוחה למגוון רחב של מכשירים היא מודלים עד 1.5–2 GB. בפרויקט אחד לאפליקציה פיננסית, בחרנו ב-Llama-3.2-1B Q4_K_M, ששמר על שימוש בזיכרון מתחת ל-1 GB ב-iPhone SE. מהירות היצירה הייתה 25–30 t/s, מספיק לתשובות לשאלות. הגבלת תרמית מוזערה על ידי הגבלת ההקשר ל-1024 טוקנים.

בעיות ופתרונות ל-LLM במכשיר

בעיה פתרון
OOM בהקשר גדול הגבל n_ctx ל-1024–2048 טוקנים
הגבלה תרמית נטר את thermalState, הפסק בין יצירות
קובץ GGUF פגום אמת SHA256 לאחר הורדה
מהירות נמוכה במכשירים ישנים השתמש במודלים של 1B עם קוונטיזציה Q4

איך לבנות את llama.cpp ל-iOS?

# Клонируем репозиторий
git clone https://github.com/ggerganov/llama.cpp
cd llama.cpp
# Сборка через CMake для iOS
cmake -B build-ios \
  -DCMAKE_TOOLCHAIN_FILE=ios.toolchain.cmake \
  -DPLATFORM=OS64 \ # arm64 only
  -DLLAMA_METAL=ON \ # Metal GPU ускорение
  -DLLAMA_STATIC=ON
cmake --build build-ios --config Release

תוצאה — ספרייה סטטית # Клонируем репозиторий git clone https://github.com/ggerganov/llama.cpp cd llama.cpp # Сборка через CMake для iOS cmake -B build-ios \ -DCMAKE_TOOLCHAIN_FILE=ios.toolchain.cmake \ -DPLATFORM=OS64 \ # arm64 only -DLLAMA_METAL=ON \ # Metal GPU ускорение -DLLAMA_STATIC=ON cmake --build build-ios --config Release . צור Swift Package עם כותרת C-bridging:

// llama_bridge.h
#include "llama.h"

// Обёртки для Swift-дружественного API
void* llama_create_context(const char* model_path, int n_ctx, int n_gpu_layers);
const char* llama_generate_token(void* ctx, const char* prompt);
void llama_free_context(void* ctx);

libllama.a — מספר השכבות המועברות ל-GPU של Metal. ערך של // llama_bridge.h #include "llama.h" // Обёртки для Swift-дружественного API void* llama_create_context(const char* model_path, int n_ctx, int n_gpu_layers); const char* llama_generate_token(void* ctx, const char* prompt); void llama_free_context(void* ctx); פירושו כל השכבות על GPU. ב-iPhone 14 עם 6 GB זיכרון מאוחד — השתמש ב-n_gpu_layers. במכשירים עם 3 GB — נסה: יותר מדי שכבות על GPU גורמות ל-OOM.

עטיפת Swift לסטרימינג טוקנים

import Foundation

actor LlamaSession {
    private var context: OpaquePointer?
    private var model: OpaquePointer?

    func load(modelPath: String, contextSize: Int32 = 2048, gpuLayers: Int32 = -1) throws {
        var params = llama_model_default_params()
        params.n_gpu_layers = gpuLayers
        model = llama_load_model_from_file(modelPath, params)
        guard model != nil else {
            throw LlamaError.modelLoadFailed
        }

        var ctxParams = llama_context_default_params()
        ctxParams.n_ctx = UInt32(contextSize)
        ctxParams.n_batch = 512
        context = llama_new_context_with_model(model, ctxParams)
    }

    func generate(prompt: String) -> AsyncThrowingStream<String, Error> {
        AsyncThrowingStream { continuation in
            Task.detached(priority: .userInitiated) {
                // Токенизация
                var tokens = [llama_token](repeating: 0, count: 4096)
                let nTokens = llama_tokenize(self.model, prompt, Int32(prompt.utf8.count), &tokens, 4096, true, false)

                // Инференс — по одному токену
                for i in 0..<nTokens {
                    llama_batch_add(&batch, tokens[Int(i)], llama_pos(i), [0], false)
                }

                while true {
                    llama_decode(self.context, batch)
                    let nextToken = llama_sample_token_greedy(self.context, &candidates)
                    if nextToken == llama_token_eos(self.model) {
                        break
                    }

                    // Конвертация токена в строку
                    var buf = [Int8](repeating: 0, count: 64)
                    llama_token_to_piece(self.model, nextToken, &buf, 64, 0, true)
                    let piece = String(cString: buf)
                    continuation.yield(piece)
                }
                continuation.finish()
            }
        }
    }
}

סטרימינג טוקנים דרך -1 — משתמשים רואים טקסט בזמן יצירתו, ללא המתנה לתשובה המלאה. זה קריטי ל-UX: 10 טוקנים בשנייה מרגישים מקובלים כשהטקסט מופיע בהדרגה.

למה אילוצים תרמיים קריטיים?

Llama.cpp ב-iPhone מחמם את המכשיר במהלך יצירה ממושכת. הגבלת iOS: כשהמערכת מתחממת, היא מפחיתה את מהירות השעון, ומהירות היצירה יורדת מ-25 t/s ל-8–10 t/s. זו לא תקלה — זו התנהגות מערכת.

פתרון מעשי: הגבל את ההקשר המקסימלי (-1) ל-1024–2048 למפגשים קצרים. הפסק בין בקשות. נטר את import Foundation actor LlamaSession { private var context: OpaquePointer? private var model: OpaquePointer? func load(modelPath: String, contextSize: Int32 = 2048, gpuLayers: Int32 = -1) throws { var params = llama_model_default_params() params.n_gpu_layers = gpuLayers model = llama_load_model_from_file(modelPath, params) guard model != nil else { throw LlamaError.modelLoadFailed } var ctxParams = llama_context_default_params() ctxParams.n_ctx = UInt32(contextSize) ctxParams.n_batch = 512 context = llama_new_context_with_model(model, ctxParams) } func generate(prompt: String) -> AsyncThrowingStream<String, Error> { AsyncThrowingStream { continuation in Task.detached(priority: .userInitiated) { // Токенизация var tokens = [llama_token](repeating: 0, count: 4096) let nTokens = llama_tokenize(self.model, prompt, Int32(prompt.utf8.count), &tokens, 4096, true, false) // Инференс — по одному токену for i in 0..<nTokens { llama_batch_add(&batch, tokens[Int(i)], llama_pos(i), [0], false) } while true { llama_decode(self.context, batch) let nextToken = llama_sample_token_greedy(self.context, &candidates) if nextToken == llama_token_eos(self.model) { break } // Конвертация токена в строку var buf = [Int8](repeating: 0, count: 64) llama_token_to_piece(self.model, nextToken, &buf, 64, 0, true) let piece = String(cString: buf) continuation.yield(piece) } continuation.finish() } } } } ב-iOS:

NotificationCenter.default.addObserver(forName: ProcessInfo.thermalStateDidChangeNotification, ...) { _ in
    let state = ProcessInfo.processInfo.thermalState
    if state == .critical || state == .serious {
        // Приостановить генерацию, уведомить пользователя
    }
}

טעויות אינטגרציה נפוצות

  • הקשר גדול מדי — בחר n_ctx ≤ 2048 למכשירים ניידים.
  • התעלמות מהגבלה תרמית — נטר את thermalState והפסק.
  • גרסת מודל שגויה — אמת תאימות קובץ GGUF עם ה-build שלך של llama.cpp.
  • חוסר אימות hash — קבצים פגומים גורמים לקריסות.

Android: llama.cpp דרך NDK

// CMakeLists.txt в jni/
add_library(llama_jni SHARED llama_jni.cpp)
target_link_libraries(llama_jni llama ggml)

// Kotlin side
class LlamaEngine {
    init {
        System.loadLibrary("llama_jni")
    }

    external fun loadModel(modelPath: String, nGpuLayers: Int): Long // возвращает handle
    external fun generateNext(handle: Long, tokens: IntArray): String
    external fun freeModel(handle: Long)
}

ב-Android — backend של Vulkan במקום Metal: כלול את AsyncThrowingStream ב-CMakeLists. נתמך במכשירים עם Vulkan 1.1+, כמעט כל אלה עם Android 10+.

בעיה ב-Android: לתהליך אין מגבלת זיכרון כמשאב משותף — המערכת עשויה להרוג את האפליקציה (n_ctx) כשאין מספיק RAM ללא אזהרה. ProcessInfo.processInfo.thermalState — ההזדמנות האחרונה לשחרר הקשר לפני סיום התהליך.

הורדת מודל: התקדמות ואימות

קבצי GGUF שוקלים 1–4 GB. הורד דרך NotificationCenter.default.addObserver(forName: ProcessInfo.thermalStateDidChangeNotification, ...) { _ in let state = ProcessInfo.processInfo.thermalState if state == .critical || state == .serious { // Приостановить генерацию, уведомить пользователя } } (iOS) או // CMakeLists.txt в jni/ add_library(llama_jni SHARED llama_jni.cpp) target_link_libraries(llama_jni llama ggml) // Kotlin side class LlamaEngine { init { System.loadLibrary("llama_jni") } external fun loadModel(modelPath: String, nGpuLayers: Int): Long // возвращает handle external fun generateNext(handle: Long, tokens: IntArray): String external fun freeModel(handle: Long) } עם LLAMA_VULKAN=ON (Android). אימות SHA256 הוא חובה: לאחר ההורדה, חשב את ה-hash והשווה עם הצפוי מהמאגר ב-HuggingFace. GGUF פגום גורם לקריסה במהלך ניתוח הכותרת או מאוחר יותר במהלך הסקה — עדיף לתפוס אותו באימות.

הרשת הניידת פועלת מהר יותר ללא השהיית רשת, מה שחשוב במיוחד ליישומים רגישים לזמן. חיסכון בעלויות: פתרון לא מקוון לחלוטין מבטל הוצאות תשתית שרת.

מה כלול באינטגרציה

  1. ניתוח צי המכשירים ובחירת מודל קוונטיזציה אופטימלי
  2. בניית llama.cpp ל-iOS (Metal) ו/או Android (Vulkan)
  3. פיתוח עטיפת Swift/Kotlin עם סטרימינג טוקנים אסינכרוני
  4. יישום הורדת מודל עם התקדמות ואימות SHA256
  5. ממשק צ'אט עם אינדיקציית מצב תרמי
  6. בדיקות עומס במכשירים אמיתיים וכיוונון פרמטרי הקשר
  7. תיעוד אינטגרציה ותמיכה במהלך ההשקה

לוחות זמנים משוערים

פלטפורמה אחת, ממשק צ'אט בסיסי עם מודל נבחר — מ-3 שבועות. שתי הפלטפורמות, מספר אפשרויות מודל, הורדה ברקע, ניהול הקשר — מ-7 שבועות. העלות מחושבת באופן אישי.

הניסיון שלנו: 5 שנים בפיתוח נייד ומעל 20 פרויקטים עם ML במכשיר. אנו מבטיחים שהפתרון עובד במכשירי היעד לאחר בדיקות. קבלו ייעוץ על בחירת מודל והערכת פרויקט. הזמינו אינטגרציה וראו את היתרונות של עוזר AI לא מקוון.