🦀

ربط المحركات وأول استنتاج محلي

SYS.TIME12 أغسطس 2026 - 14:00 PM (GMT+3)
CATEGORYالتأسيس

ربط المحركات وتشغيل أول استنتاج محلي

في هذه المرحلة، أكملنا الجسر الكامل بين Rust ومحرك النصوص (llama.cpp) وشغّلنا أول inference محلي حقيقي على الجهاز بدون أي اتصال بالإنترنت.

ما تم إنجازه

البنية التحتية للـ FFI

  • بناء text_engine (llama.cpp) من المصدر بدون أدوات خارجية، وإنتاج libllama.a + مكتبات ggml.
  • كتابة build.rs لربط كل المكتبات الثابتة (libllama.a, libggml.a, libggml-base.a, libggml-cpu.a) مع OpenMP.
  • كتابة pz_text_engine_wrapper.cpp — C++ wrapper يُخفي تعقيدات llama.cpp API ويعرض 3 دوال نظيفة:
    • pz_llama_load(path) — تحميل نموذج GGUF
    • pz_llama_complete(model, prompt, max_tokens) — توليد نص
    • pz_llama_free(model) — تحرير الذاكرة
  • تعريف FFI bindings في src/ffi/llama.rs بصيغة unsafe extern "C" المتوافقة مع Rust 2024.

الخبراء (Experts)

  • OcrExpert — stub يقبل Input::Image (جاهز لربط vision_engine لاحقاً)
  • LlamaExpert — يحمّل نموذج GGUF ويولّد نصاً عبر pz_llama_complete

النموذج

  • Qwen2.5-0.5B-Instruct-Q4_K_M (~468MB) — نموذج متعدد اللغات يدعم العربية، يعمل محلياً بالكامل.
  • مُخزَّن في main/model/qwen2.5-0.5b-instruct-q4_k_m.gguf

الهيكل الحالي

main/
├── build.rs                        ← يبني الـ wrapper ويربط المكتبات
├── pz_text_engine_wrapper.cpp      ← C++ wrapper لـ llama.cpp
├── model/
│   └── qwen2.5-0.5b-instruct-q4_k_m.gguf
└── src/
    ├── main.rs
    ├── ffi/llama.rs                ← FFI bindings
    ├── experts/
    │   ├── ocr_expert.rs
    │   └── llama_expert.rs
    ├── manager/mod.rs
    └── model/mod.rs

نتيجة التشغيل النهائية ✅

السؤال: ما هي عاصمة المملكة العربية السعودية؟

الجواب:

النتيجة: عاصمة المملكة العربية السعودية هي الرياض. (الخبير: llama-text)

🎯 رد نظيف، صحيح، ومختصر — بدون أي تكرار

كيف جاوب؟

المستخدم ──────────────────────────────────────────────────►
 "ما هي عاصمة المملكة العربية السعودية؟"


 [Manager / Orchestrator - Rust]
 يتعرف: Input::Text → يوجه لـ LlamaExpert


 [LlamaExpert - Rust]
 يبني chat prompt بتنسيق Qwen2.5:
 ┌─────────────────────────────────────────┐
 │ <|im_start|>system                      │
 │ أنت مساعد ذكي...         <|im_end|>    │
 │ <|im_start|>user                        │
 │ ما هي عاصمة...؟          <|im_end|>    │
 │ <|im_start|>assistant                   │
 └─────────────────────────────────────────┘

          ▼  unsafe FFI عبر pz_llama_complete()
 [pz_text_engine_wrapper.cpp - C++]
 - llama_tokenize() → يحوّل النص لأرقام
 - llama_decode()   → يحسب احتماليات الكلمات
 - Sampler Chain:
     penalty(1.15) → يمنع التكرار
     temp(0.7)     → يركّز الاختيار
     dist(42)      → يختار الـ token النهائي
 - يولّد كلمة بعد كلمة حتى <|im_end|>


 "عاصمة المملكة العربية السعودية هي الرياض."

لماذا اختفى التكرار؟

  • Repetition Penalty 1.15: يُقلّل احتمالية إعادة الـ tokens المستخدمة مؤخراً
  • Temperature 0.7: يجعل التوليد أكثر تركيزاً (أقل عشوائية)
  • Chat Template: يُخبر النموذج بدوره ويضع حداً واضحاً للرد عند <|im_end|>

الخطوة التالية

  • تنفيذ OcrExpert الفعلي عبر ربط vision_engine (ONNX Runtime)