Skip to content

Repository files navigation

Local Summarizer — תמלול וסיכום ישיבות אופליין

Offline Android app that transcribes meeting recordings with whisper.cpp and summarizes them in Hebrew with llama.cpp (Qwen 2.5 Instruct GGUF). All processing happens on-device; the network is used only to fetch models and app updates.

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


הורדה והתקנה (Download)

  1. פותחים בטלפון את דף ה-Release ומורידים את app-release.apk.
  2. באנדרואיד מאשרים התקנה ממקור לא מוכר (הטלפון יציע את זה בעצמו).
  3. מתקינים ופותחים.

ה-APK נבנה מחדש בכל דחיפה לענף ומוחלף באותו קישור, כך שהקישור תמיד מצביע על הגרסה האחרונה. תומך ב-arm64 בלבד (כל טלפון מודרני), אנדרואיד 8.0 ומעלה.

עדכון האפליקציה

אחרי ההתקנה הראשונה אין צורך לחזור לדף — הגדרות → גרסת האפליקציה → בדיקת עדכון משווה את הגרסה המותקנת מול ה-Release ומתקינה את החדשה.

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

שדה הטוקן שבאותו מסך נשאר למקרה שתחזירו את המאגר להיות פרטי; הוא נשמר באחסון הפרטי של האפליקציה, לא נכלל בגיבוי, ונשלח רק ל-github.com — לא מועבר הלאה לשרת ההורדה שאליו GitHub מפנה.

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

הורדת מודלים (Models)

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

  • ההורדה רצה דרך מנהל ההורדות של אנדרואיד, כך שהיא ממשיכה גם כשיוצאים מהאפליקציה ומתאוששת מניתוקי רשת — חשוב לקובץ של כמה ג׳יגה.
  • ברירת המחדל היא Wi-Fi בלבד; אפשר לבטל בתיבת הסימון אם רוצים להוריד ברשת סלולרית.
  • בדיקת עדכונים בראש הסעיף בודקת מול השרת אם קיימת גרסה חדשה יותר של מודל שכבר הורד.
  • אפשר גם למחוק מודל שהורד, או לבחור מחדש מודל קיים בלי להוריד שוב.

מי שכבר הוריד קובץ בעצמו יכול פשוט לבחור אותו — כפתור "בחירת קובץ" עדיין שם.

מה יש ברשימה

ייעוד מודל גודל
תמלול Whisper large-v3-turbo ~1.6GB
תמלול Whisper small ~490MB
תמלול Whisper base ~150MB (לבדיקה ראשונה בלבד)
סיכום Qwen2.5 3B Instruct Q4_K_M ~2GB
סיכום Qwen2.5 7B Instruct Q4_K_M ~4.7GB (דורש 12GB RAM)

המלצה למכשיר עם 12GB RAM: הורידו קודם את Whisper base ואת Qwen 3B, הריצו הקלטה קצרה כדי לוודא שהכול עובד, ורק אז הורידו את large-v3-turbo ואת 7B.

הערה על עברית: ל-ivrit.ai יש מודלי Whisper מכווננים לעברית שמדויקים יותר מהמודלים הרשמיים, והם לא ברשימה כי לא אימתתי שקיימת להם גרסת GGML מוכנה. אם תמצאו אחת — הורידו ידנית ובחרו אותה דרך "בחירת קובץ".

מגבלה: מודל סיכום חייב להיות קובץ GGUF יחיד. קובץ מפוצל (‏...-00001-of-00002.gguf) לא ייטען, כי llama.cpp גוזר את נתיבי החלקים האחרים משם הקובץ. כל המודלים ברשימה הם קובץ יחיד.

שימוש (Usage)

  1. הגדרות → מורידים מודל תמלול ומודל סיכום מהרשימה (או בוחרים קבצים קיימים).
  2. באותו מסך אפשר לערוך את הפרומפט הראשי — הנחיית המערכת שקובעת איך ייראה הסיכום (ברירת המחדל מייצרת תקציר מנהלים, נושאים, החלטות, משימות ושאלות פתוחות בעברית).
  3. במסך הראשי בוחרים קובץ שמע ‏(M4A, MP3, WAV, AAC, OGG) ולוחצים תמלל וסכם.
  4. העיבוד רץ ברקע עם התראה מתמדת; אפשר לצאת מהאפליקציה ולחזור.
  5. בסיום: העתקה ללוח, שיתוף, או ייצוא ל-.md / .txt. כל ישיבה נשמרת בהיסטוריה.

כמה זמן זה לוקח

העיבוד מקומי לגמרי, ולכן איטי יותר משירותי ענן. לסדר גודל, בפגישה של שעה על מכשיר דגל: פענוח שמע — שניות; תמלול — בערך 10–25 דקות; סיכום — עוד כמה דקות (יותר עם מודל 7B). כדאי להריץ כשהטלפון בטעינה.

איך זה בנוי (Architecture)

בחירת קובץ (SAF)
      ↓
פענוח שמע  MediaCodec → PCM 16kHz מונו float, נכתב לקובץ זמני
      ↓
טעינת Whisper → תמלול (התקדמות חיה) → שחרור Whisper מהזיכרון
      ↓
טעינת Llama → סיכום ChatML → שחרור Llama מהזיכרון
      ↓
תוצאה + היסטוריה + ייצוא

הרצה סדרתית בכוונה: שני המודלים לעולם לא נמצאים בזיכרון בו-זמנית, אחרת מכשיר עם 12GB היה נחנק. כל הצינור רץ ב-ForegroundService עם WakeLock, כדי שהמערכת לא תהרוג אותו באמצע עיבוד ארוך.

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

זיכרון: שעת שמע היא כ-230MB של PCM — הרבה מעבר למגבלת ה-Java heap של אנדרואיד. לכן השמע המפוענח נכתב לקובץ זמני ונקרא ישירות ב-C++, ולא מוחזק במערך Java.

מודלים: נטענים ישירות מהמיקום שבחרתם דרך /proc/self/fd ‏(mmap, בלי העתקה), עם נפילה לאחור להעתקה חד-פעמית אם ספק הקבצים לא תומך.

מחסנית טכנולוגית

Kotlin · Jetpack Compose · Material 3 · MVVM · Coroutines/Flow · DataStore · C++ NDK 28 · whisper.cpp v1.9.3 · llama.cpp b10630 · ggml משותף לשני המנועים · ARM NEON עם dotprod ו-i8mm · ‏-O3 בכל וריאנטי הבנייה · arm64-v8a.

בחירת קוד לפי המעבד: ggml נבנה כאן עם וריאנט נפרד לכל רמת תכונות של ARM (‏armv8.0 בסיסי, armv8.2 עם dotprod ו-fp16, armv8.6 עם i8mm), והאפליקציה טוענת בזמן ריצה את הווריאנט המהיר ביותר שהמכשיר תומך בו. כך ה-S26 Ultra מקבל את הקרנלים המהירים בלי שהאפליקציה תקרוס במכשירים ישנים יותר.

ההאצה היא על ה-CPU: ה-backends של Vulkan/OpenCL ב-llama.cpp עדיין לא יציבים על אנדרואיד (תלות בדרייברים, קריסות על חלק מה-GPU-ים), והבנייה מוכנה להוספתם בהמשך.

בנייה מקומית (Building)

git clone --recurse-submodules https://github.com/Stastyle/Local-Summerizer
cd Local-Summerizer
./gradlew assembleRelease   # app/build/outputs/apk/release/app-release.apk

דרישות: JDK 21, Android SDK 35, NDK 28, CMake 3.22+.

מפתח החתימה

מפתח החתימה של גרסת ה-release אינו נמצא במאגר. ה-CI משחזר אותו מ-secret בשם ANDROID_KEYSTORE_B64 (עם הסיסמה ב-ANDROID_KEYSTORE_PASSWORD) לפני הבנייה.

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

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

לבנייה מקומית חתומה:

export ANDROID_KEYSTORE_PATH=/path/to/release.keystore
export ANDROID_KEYSTORE_PASSWORD=...
./gradlew assembleRelease

בלי משתני הסביבה האלה assembleRelease עדיין עובד ומייצר APK לא חתום.

כשמשהו נשבר (Diagnostics)

הגדרות → אבחון → הפקת דוח → העתקה. הדוח כולל דגם ומכשיר, גודל דף (4KB/16KB), האם ספריות ה-CPU של ggml באמת נמצאות בתיקיית הספריות, כמה backends נרשמו, הזנב של הלוג של ggml/llama/whisper, ובאיזה שלב הריצה האחרונה נעצרה. אין בו שמע, תמליל או סיכום.

הדוח כולל גם את רשומות יציאת התהליכים של אנדרואיד עצמו. זו הדרך היחידה לראות קריסה נייטיבית בלי מחשב: מ-API 31 המערכת שומרת את ה-tombstone של הקריסה והאפליקציה יכולה לקרוא את שלה — בלי הרשאה, בלי adb ובלי root. הרשומות יושבות בבאפר מעגלי משותף לכל האפליקציות, ולכן הן עלולות להימחק; הדוח מבחין בין "אין קריסה" לבין "הראיה נמחקה".

פענוח כתובות ל-backtrace

ה-.so שבתוך ה-APK מקוצצים, ולכן backtrace הוא כתובות בלבד. כל בנייה ב-CI מעלה ארטיפקט בשם local-summarizer-symbols עם אותן ספריות לפני הקיצוץ — בלי העותק מהבנייה המדויקת שקרסה אי אפשר לפענח כלום:

gh run download <run-id> --name local-summarizer-symbols -D symbols
$ANDROID_NDK/prebuilt/*/bin/ndk-stack -sym symbols/**/arm64-v8a -dump crash.txt

בדיקות (Tests)

./gradlew testDebugUnitTest

מכוסים: נכונות הרסמפלר (קצב פלט מדויק מכל קצבי הקלט הנפוצים, שימור אמפליטודה בטווח הדיבור, דיכוי aliasing מעל 8kHz, ועקביות בין קלט מקוטע לקלט רציף), ותבנית ה-ChatML והעטיפות בעברית. ה-CI מריץ אותם לפני כל בנייה, ונכשל אם ספריות ה-CPU של ggml לא נארזו ל-APK.

פרטיות

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

לאפליקציה יש הרשאת INTERNET, והיא יוצאת לרשת בשני מקרים בלבד, שניהם ביוזמתכם:

  • HuggingFace — הורדת קובצי מודלים ובדיקת עדכונים עבורם.
  • GitHub — בדיקת גרסה חדשה של האפליקציה והורדת ה-APK.

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

בנוסף, גיבוי אנדרואיד האוטומטי מכובה כדי שתמלילים לא יסונכרנו ל-Google Drive.

About

Offline Android app that transcribes meeting recordings with whisper.cpp and summarizes them in Hebrew with llama.cpp - fully on-device

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages